Megosztás a következőn keresztül:


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ó GetPinnableReferencetípus példányával. A metódusnak nem ref 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
        }
    }
    
  • Rögzített méretű pufferrel.

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:

Lásd még