rögzített utasítás – változó rögzítése mutatóműveletekhez
Az fixed
utasítás megakadályozza, hogy a szemétgyűjtő áthelyezjen egy áthelyezhető változót, és egy mutatót deklaráljon ehhez a változóhoz. A rögzített vagy rögzített változó címe nem változik az utasítás végrehajtása során. A deklarált mutatót csak a megfelelő fixed
utasításban használhatja. A deklarált mutató olvasható, és nem módosítható:
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.
Feljegyzés
Az fixed
utasítást csak nem biztonságos környezetben használhatja. A nem biztonságos blokkokat tartalmazó kódot az AllowUnsafeBlocks fordítóbeállítással kell lefordítani.
A deklarált mutató inicializálható az alábbiak szerint:
Tömbbel, ahogy a cikk elején látható példa is mutatja. Az inicializált mutató az első tömbelem címét tartalmazza.
Egy változó címével. Használja az operátor címét
&
az alábbi példában látható módon:unsafe { int[] numbers = [10, 20, 30]; fixed (int* toFirst = &numbers[0], toLast = &numbers[^1]) { Console.WriteLine(toLast - toFirst); // output: 2 } }
Az objektummezők egy másik példa az áthelyezhető változókra, amelyek rögzíthetők.
Ha az inicializált mutató egy objektummező vagy tömbelem címét tartalmazza, az
fixed
utasítás garantálja, hogy a szemétgyűjtő nem helyezi át vagy nem helyezi el a benne lévő objektumpéldányt az utasítás törzsének végrehajtása során.A metódust megvalósító
GetPinnableReference
típus példányával. A metódusnak nemref
felügyelt típusú változót kell visszaadnia. A .NET-típusok System.Span<T> , és System.ReadOnlySpan<T> használja ezt a mintát. Az átfedő példányokat az alábbi példában látható módon rögzítheti: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 } }
További információ: API-referencia Span<T>.GetPinnableReference() .
Sztringgel, ahogy az alábbi példa mutatja:
unsafe { var message = "Hello!"; fixed (char* p = message) { Console.WriteLine(*p); // output: H } }
Lefoglalhat memóriát a veremen, ahol nincs szemétgyűjtés tárgya, ezért nem kell rögzíteni. Ehhez használjon egy stackalloc
kifejezést.
A kulcsszóval fixed
rögzített méretű puffert is deklarálhat.
C# nyelvspecifikáció
További információt a C# nyelvspecifikációjának alábbi szakaszaiban talál: