Sampai C# 11, field struct dilarang bertipe ref. C# 11 mengizinkannya dengan satu syarat: field tersebut hanya boleh hidup di dalam ref struct, tipe yang wajib tinggal di stack sebagaimana dibahas pada bab Ref Struct di section Struct, Record, dan Enum. Gabungan keduanya menghasilkan struct kecil yang menunjuk data di tempat lain, fondasi yang dipakai tipe seperti Span<T> di internal runtime.

Aturan Deklarasi #

  • Field ref hanya boleh dideklarasikan di dalam ref struct; struct biasa yang menampungnya ditolak compiler.
  • Field tersebut menyimpan referensi ke data milik pihak lain, bukan salinan nilainya.
  • Sama seperti ref local, penugasan awal memakai bentuk = ref ... dan isi field dapat dipindahkan ke tujuan lain kapan saja.

Contoh: Sel yang Menunjuk Array #

csharp
internal ref struct Sel
{
    public ref int Nilai;

    public Sel(ref int awal)
    {
        Nilai = ref awal;
    }
}

int[] data = { 10, 20, 30 };
Sel sel = new Sel(ref data[1]);
Console.WriteLine(sel.Nilai);
sel.Nilai = 99;
Console.WriteLine(data[1]);

sel.Nilai = ref data[2];
sel.Nilai = 55;
Console.WriteLine(data[2]);

Output yang Dihasilkan:

text
20
99
55

Mari kita bedah baris demi baris:

  1. public ref int Nilai;: field bertipe referensi menandai Sel sebagai ref struct yang hanya boleh di stack.
  2. Nilai = ref awal: constructor menyimpan alias ke elemen array yang diterima; tidak ada penyalinan nilai pada baris ini.
  3. sel.Nilai = 99;: penulisan melalui field langsung mengubah data[1], seperti ditunjukkan output 99.
  4. sel.Nilai = ref data[2];: tujuan referensi dipindahkan ke elemen lain tanpa membentuk Sel baru, lalu penugasan berikutnya menulis 55 ke data[2].

Sambungan dengan Aturan Escape #

Compiler menegakkan batas rentang hidup pada setiap penugasan ke ref field: referensi tidak boleh menunjuk data yang rentangnya lebih pendek daripada rentang hidup struct penampungnya. Aturan ini yang mencegah field menunjuk memori yang sudah tak berlaku. Modifier scoped pada bab berikutnya memberi penulis tipe kendali tambahan atas batas tersebut.