fixed
ステートメントは、ガベージ コレクターが移動可能な変数を再配置するのを防ぎ、その変数へのポインターを宣言します。 固定変数または固定変数のアドレスは、ステートメントの実行中に変更されません。 宣言されたポインターは、対応する fixed
ステートメント内でのみ使用できます。 宣言されたポインターは読み取り時のみであり、変更できません。
unsafe
{
byte[] bytes = [1, 2, 3];
fixed (byte* pointerToFirst = bytes)
{
Console.WriteLine($"The address of the first array element: {(long)pointerToFirst:X}.");
Console.WriteLine($"The value of the first array element: {*pointerToFirst}.");
}
}
// Output is similar to:
// The address of the first array element: 2173F80B5C8.
// The value of the first array element: 1.
注
fixed
ステートメントは、安全でないコンテキストでのみ使用できます。 安全でないブロックを含むコードは、 AllowUnsafeBlocks コンパイラ オプションを使用してコンパイルする必要があります。
宣言されたポインターは、次のように初期化できます。
この記事の冒頭の例に示すように、配列を使用します。 初期化されたポインターには、最初の配列要素のアドレスが含まれています。
変数のアドレスを使用します。 次の例に示すように、 address-of
&
演算子を使用します。unsafe { int[] numbers = [10, 20, 30]; fixed (int* toFirst = &numbers[0], toLast = &numbers[^1]) { Console.WriteLine(toLast - toFirst); // output: 2 } }
オブジェクト フィールドは、固定できる移動可能な変数のもう 1 つの例です。
初期化されたポインターにオブジェクト フィールドまたは配列要素のアドレスが含まれている場合、
fixed
ステートメントは、ステートメント本体の実行中に、ガベージ コレクターが含まれるオブジェクト インスタンスを再配置または破棄しないことを保証します。GetPinnableReference
という名前のメソッドを実装する型のインスタンス。 そのメソッドは、アンマネージ型のref
変数を返す必要があります。 .NET 型 System.Span<T> し、このパターンを使用 System.ReadOnlySpan<T> 。 次の例に示すように、スパン インスタンスをピン留めできます。unsafe { int[] numbers = [10, 20, 30, 40, 50]; Span<int> interior = numbers.AsSpan()[1..^1]; fixed (int* p = interior) { for (int i = 0; i < interior.Length; i++) { Console.Write(p[i]); } // output: 203040 } }
詳細については、 Span<T>.GetPinnableReference() API リファレンスを参照してください。
次の例に示すように、文字列を使用します。
unsafe { var message = "Hello!"; fixed (char* p = message) { Console.WriteLine(*p); // output: H } }
固定サイズのバッファーを使用します。
スタックにメモリを割り当てることができます。メモリはガベージ コレクションの対象ではないため、ピン留めする必要はありません。 そのためには、 stackalloc
式を使用します。
fixed
キーワードを使用して、固定サイズのバッファーを宣言することもできます。
C# 言語仕様
詳細については、「C# 言語仕様」の次のセクションを参照してください。
こちらも参照ください
.NET