Bagikan melalui


pernyataan tetap - sematkan variabel untuk operasi penunjuk

Pernyataan tersebut fixed mencegah pengumpul sampah merelokasi variabel yang dapat dipindahkan dan mendeklarasikan penunjuk ke variabel tersebut. Alamat variabel tetap, atau disematkan, tidak berubah selama eksekusi pernyataan. Anda dapat menggunakan penunjuk yang dideklarasikan hanya di dalam pernyataan yang fixed sesuai. Penunjuk yang dideklarasikan bersifat baca-saja dan tidak dapat dimodifikasi:

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.

Catatan

Anda hanya dapat menggunakan fixed pernyataan dalam konteks yang tidak aman . Kode yang berisi blok tidak aman harus dikompilasi dengan opsi compiler AllowUnsafeBlocks.

Anda dapat menginisialisasi pointer yang dideklarasikan sebagai berikut:

  • Dengan array, seperti yang ditunjukkan contoh di awal artikel ini. Penunjuk yang diinisialisasi berisi alamat elemen array pertama.

  • Dengan alamat variabel. Gunakan alamat & operator, seperti yang ditunjukkan contoh berikut:

    unsafe
    {
        int[] numbers = [10, 20, 30];
        fixed (int* toFirst = &numbers[0], toLast = &numbers[^1])
        {
            Console.WriteLine(toLast - toFirst);  // output: 2
        }
    }
    

    Bidang objek adalah contoh lain dari variabel yang dapat dipindahkan yang dapat disematkan.

    Ketika pointer yang diinisialisasi berisi alamat bidang objek atau elemen array, fixed pernyataan menjamin bahwa pengumpul sampah tidak merelokasi atau membuang instans objek yang berisi selama eksekusi isi pernyataan.

  • Dengan instans jenis yang mengimplementasikan metode bernama GetPinnableReference. Metode tersebut harus mengembalikan ref variabel dari jenis yang tidak dikelola. Jenis .NET System.Span<T> dan System.ReadOnlySpan<T> menggunakan pola ini. Anda dapat menyematkan instans rentang, seperti yang ditunjukkan contoh berikut:

    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
        }
    }
    

    Untuk informasi selengkapnya, lihat referensi API Span<T>.GetPinnableReference().

  • Dengan string, seperti yang ditunjukkan contoh berikut:

    unsafe
    {
        var message = "Hello!";
        fixed (char* p = message)
        {
            Console.WriteLine(*p);  // output: H
        }
    }
    
  • Dengan buffer ukuran tetap.

Anda dapat mengalokasikan memori pada tumpukan, di mana memori tidak tunduk pada pengumpulan sampah dan oleh karena itu tidak perlu disematkan. Untuk melakukannya, gunakan sebuah stackalloc ekspresi .

Anda juga dapat menggunakan fixed kata kunci untuk mendeklarasikan buffer ukuran tetap.

Spesifikasi bahasa C#

Untuk informasi selengkapnya, lihat bagian berikut dari spesifikasi bahasa C#:

Lihat juga