この記事では、.Net Core で ref と Span
2. Ref キーワード
ref キーにしろ out キーにしろ、C 言語でのポインタの操作と同様に、このような高度な構文は常に何らかの副作用を伴いますが、理解と操作が難しい言語機能です。私はこれが大したことではないと思いますし、すべての C# 開発者がこれらの内部動作メカニズムを深く理解する必要があるわけではありません。複雑さは関係なく、人々に自由な選択肢を提供するだけであり、リスクと柔軟性は決して両立しないと思います。 。
参照とポインターの類似性を説明するために、いくつかの例を見てみましょう。 もちろん、次の使用方法は C# 7.0 より前でも使用できます。
public static void IncrementByRef(ref int x) { x++; } public unsafe static void IncrementByPointer(int* x) { (*x)++; }
上記の 2 つの関数は、それぞれ ref と unsafe ポインターを使用します。パラメータ +1 を完成させます。
int i = 30; IncrementByRef(ref i); // i = 31 unsafe{ IncrementByPointer(&i); } // i = 32
1.ref ローカル (ローカル変数の参照)
int i = 42; ref var x = ref i; x = x + 1; // i = 43
この例では、ローカル i の参照 x です。変数、x を変更すると、i 変数の値も変更されます。
2.ref returns (戻り値参照)
ref returns は、C# 7 の強力な機能です。次のコードは、その機能を最もよく反映しています:
public static ref int GetArrayRef(int[] items, int index) => ref items[index];
System.Span は、System.Memory.dll アセンブリの下にある .Net Core コアの一部です。現在、この機能は独立していますが、将来 CoreFx に統合される可能性があります
使用方法?次の NuGet パッケージは、.Net Core 2.0 SDK によって作成されたプロジェクトの下で参照されます:
<ItemGroup> <PackageReference Include="System.Memory" Version="4.4.0-preview1-25305-02" /> <PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.4.0-preview1-25305-02" /> </ItemGroup>
スパン機能は次のとおりです:
•配列、アンマネージ ポインタ、スタック ポインタ、固定または固定された管理データ、および値の内部領域への参照を含む、すべての連続メモリ空間の型システムを抽象化します
• CLR 標準のオブジェクト型と値型をサポートします•ジェネリクスをサポートします •独自に管理および解放する必要があるポインターとは異なり、GC をサポートします 構文的にも意味的にも ref: に関連する Span の定義を見てみましょう。
public struct Span<T> { ref T _reference; int _length; public ref T this[int index] { get {...} } ... } public struct ReadOnlySpan<T> { ref T _reference; int _length; public T this[int index] { get {...} } ... }
string content = "content-length:123"; Stopwatch watch1 = new Stopwatch(); watch1.Start(); for (int j = 0; j < 100000; j++) { int.Parse(content.Substring(15)); } watch1.Stop(); Console.WriteLine("\tTime Elapsed:\t" + watch1.ElapsedMilliseconds.ToString("N0") + "ms");
string content = "content-length:123",
string content = "content-length:123"; ReadOnlySpan<char> span = content.ToCharArray(); span.Slice(15).ParseToInt(); watch.Start(); for (int j = 0; j < 100000; j++) { int icb = span.Slice(15).ParseToInt(); } watch.Stop(); Console.WriteLine("\tTime Elapsed:\t" + watch.ElapsedMilliseconds.ToString("N0") + "ms");
以上がコード分析: ref と Span