stała instrukcja — przypinanie zmiennej dla operacji wskaźnika
Instrukcja fixed
zapobiega przeniesieniu zmiennej przenoszonej przez moduł odśmiecania pamięci i deklaruje wskaźnik do tej zmiennej. Adres stałej lub przypiętej zmiennej nie zmienia się podczas wykonywania instrukcji. Zadeklarowany wskaźnik można użyć tylko wewnątrz odpowiedniej fixed
instrukcji. Zadeklarowany wskaźnik jest odczytany i nie można go modyfikować:
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.
Uwaga
Instrukcję fixed
można używać tylko w niebezpiecznymkontekście. Kod zawierający niebezpieczne bloki należy skompilować za pomocą opcji kompilatora AllowUnsafeBlocks .
Można zainicjować zadeklarowany wskaźnik w następujący sposób:
W przypadku tablicy, jak pokazano na początku tego artykułu. Zainicjowany wskaźnik zawiera adres pierwszego elementu tablicy.
Przy użyciu adresu zmiennej. Użyj operatora address-of
&
, jak pokazano w poniższym przykładzie:unsafe { int[] numbers = [10, 20, 30]; fixed (int* toFirst = &numbers[0], toLast = &numbers[^1]) { Console.WriteLine(toLast - toFirst); // output: 2 } }
Pola obiektów to kolejny przykład zmiennych, które można przypiąć.
Gdy zainicjowany wskaźnik zawiera adres pola obiektu lub elementu tablicy,
fixed
instrukcja gwarantuje, że moduł odśmiecania pamięci nie przenosi ani nie usuwa zawierającego wystąpienia obiektu podczas wykonywania treści instrukcji.Wystąpienie typu implementujące metodę o nazwie
GetPinnableReference
. Ta metoda musi zwracać zmiennąref
typu niezarządzanego. Typy System.Span<T> platformy .NET i System.ReadOnlySpan<T> używają tego wzorca. Możesz przypiąć wystąpienia, jak pokazano w poniższym przykładzie: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 } }
Aby uzyskać więcej informacji, zobacz dokumentację interfejsu Span<T>.GetPinnableReference() API.
W przypadku ciągu, jak pokazano w poniższym przykładzie:
unsafe { var message = "Hello!"; fixed (char* p = message) { Console.WriteLine(*p); // output: H } }
Pamięć można przydzielić na stosie, gdzie nie podlega wyrzucaniu pamięci i dlatego nie musi być przypięta. W tym celu użyj stackalloc
wyrażenia .
Możesz również użyć słowa kluczowego fixed
, aby zadeklarować bufor o stałym rozmiarze.
specyfikacja języka C#
Aby uzyskać więcej informacji, zobacz następujące sekcje specyfikacji języka C#: