Struct biasa memperbolehkan field dan property diubah kapan saja setelah struct dibuat. Kebebasan tersebut sering menjadi sumber kekeliruan: sebuah method menerima salinan struct, mengubah salinannya, lalu mengira data asli ikut berubah, padahal perubahan itu tertahan di salinan. Modifier readonly pada struct menutup celah tersebut dengan memaksa seluruh isinya tetap dari awal dibuat hingga akhir masa pakai.
Masalah Struct yang Dapat Diubah #
Struct tersalin setiap kali didefinisikan ulang, diteruskan ke method, atau dikembalikan dari method. Bila struct bisa diubah, setiap salinan membawa kemungkinan perubahan yang menyimpang dari data asli. Compiler bahkan membuat salinan tambahan secara diam-diam pada situasi tertentu untuk melindungi data asal, dan perubahan yang kita lakukan justru tertahan di salinan protektif tersebut. Modifier readonly menghapus seluruh pertanyaan tersebut: tanpa kemampuan mengubah isi, tidak ada salinan yang bisa menyimpang.
Mendefinisikan Readonly Struct #
Contoh berikut mendefinisikan struct TitikKoordinat yang tidak dapat diubah, lalu menggeser titik dengan mengembalikan struct baru:
public readonly struct TitikKoordinat
{
public int X { get; }
public int Y { get; }
public TitikKoordinat(int x, int y)
{
X = x;
Y = y;
}
public TitikKoordinat Geser(int deltaX, int deltaY) =>
new TitikKoordinat(X + deltaX, Y + deltaY);
public override string ToString() => $"({X}, {Y})";
}
TitikKoordinat mulai = new TitikKoordinat(2, 5);
TitikKoordinat akhir = mulai.Geser(3, -1);
Console.WriteLine(mulai);
Console.WriteLine(akhir);Output yang Dihasilkan:
(2, 5)
(5, 4)Mari kita telaah bagian-bagian pentingnya:
public readonly struct: modifierreadonlymenyatakan seluruh isi struct tidak boleh berubah setelah dibuat; compiler menandai setiap pelanggaran sebagai galat kompilasi.public int X { get; }: property hanya memiliki aksesorget; nilai diisi satu kali lewat constructor dan tidak dapat ditimpa.Geser(int deltaX, int deltaY): method tidak mengubahthis; method mengembalikan struct baru berisi hasil pergeseran.TitikKoordinat akhir = mulai.Geser(3, -1);: variableakhirmenerima struct baru(5, 4), sementaramulaitetap(2, 5).
Upaya mengubah isi readonly struct langsung ditolak compiler. Bila kita menambahkan baris mulai.X = 9;, proses kompilasi gagal dengan pesan berikut:
error CS0200: Property or indexer 'TitikKoordinat.X' cannot be assigned to -- it is read onlyCompiler memberlakukan aturan yang sama pada anggota lain di dalam readonly struct:
- Semua field dan auto-property wajib bersifat read-only; modifier
readonlypada tiap anggota menjadi tidak perlu karena seluruh struct sudah mengikatnya. - Method tidak boleh mengisi ulang field maupun property, termasuk lewat
this; method hanya boleh membaca dan mengembalikan hasil. - Property dengan aksesor
setditolak compiler, sehingga satu-satunya jalur pengisian adalah constructor atau pengubahinit.