const
dan readonly
serupa, tetapi mereka tidak persis sama.
Sebuah const
lapangan adalah waktu kompilasi konstan, yang berarti bahwa nilai yang dapat dihitung pada saat kompilasi. Sebuah readonly
lapangan memungkinkan skenario tambahan di mana beberapa kode harus dijalankan selama konstruksi dari jenis. Setelah konstruksi, readonly
bidang tidak dapat diubah.
Misalnya, const
anggota dapat digunakan untuk mendefinisikan anggota seperti:
struct Test
{
public const double Pi = 3.14;
public const int Zero = 0;
}
Karena nilai-nilai seperti 3.14 dan 0 adalah konstanta kompilasi-waktu. Namun, pertimbangkan kasus di mana Anda mendefinisikan suatu tipe dan ingin memberikan beberapa contoh pre-fab. Misalnya, Anda mungkin ingin mendefinisikan kelas Warna dan memberikan "konstanta" untuk warna umum seperti Hitam, Putih, dll. Tidak mungkin melakukan ini dengan anggota const, karena sisi kanan bukan konstanta waktu kompilasi. Orang dapat melakukan ini dengan anggota statis biasa:
public class Color
{
public static Color Black = new Color(0, 0, 0);
public static Color White = new Color(255, 255, 255);
public static Color Red = new Color(255, 0, 0);
public static Color Green = new Color(0, 255, 0);
public static Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}
Tapi kemudian tidak ada yang bisa mencegah klien Color dari mucking dengan itu, mungkin dengan menukar nilai Hitam dan Putih. Tak perlu dikatakan, ini akan menimbulkan kekhawatiran bagi klien lain dari kelas Warna. Fitur "readonly" membahas skenario ini.
Dengan hanya memasukkan readonly
kata kunci dalam deklarasi, kami menjaga inisialisasi yang fleksibel sambil mencegah kode klien dari mucking sekitar.
public class Color
{
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
public static readonly Color Red = new Color(255, 0, 0);
public static readonly Color Green = new Color(0, 255, 0);
public static readonly Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}
Sangat menarik untuk dicatat bahwa anggota const selalu statis, sedangkan anggota readonly bisa statis atau tidak, seperti bidang biasa.
Dimungkinkan untuk menggunakan kata kunci tunggal untuk kedua tujuan ini, tetapi ini mengarah ke masalah versi atau masalah kinerja. Asumsikan sejenak bahwa kami menggunakan satu kata kunci untuk ini (const) dan pengembang menulis:
public class A
{
public static const C = 0;
}
dan pengembang lain menulis kode yang mengandalkan A:
public class B
{
static void Main() => Console.WriteLine(A.C);
}
Sekarang, dapatkah kode yang dihasilkan mengandalkan fakta bahwa AC adalah konstanta waktu kompilasi? Yaitu, bisakah penggunaan AC diganti dengan nilai 0? Jika Anda mengatakan "ya" untuk ini, maka itu berarti bahwa pengembang A tidak dapat mengubah cara AC diinisialisasi - ini mengikat tangan pengembang A tanpa izin.
Jika Anda mengatakan "tidak" untuk pertanyaan ini, maka optimasi penting tidak terjawab. Mungkin penulis A yakin bahwa AC akan selalu nol. Penggunaan const dan readonly memungkinkan pengembang A untuk menentukan maksud. Ini membuat perilaku versi yang lebih baik dan juga kinerja yang lebih baik.
static readonly
: coba gunakan const di dalamIEnumerator
yang akan memicu unrecheableyield
dan Anda akan mendapatkan "kesalahan kompiler internal" yang ditakuti . Saya tidak menguji kode di luar Unity3D, tapi saya percaya ini adalah bug mono atau .NET . Meskipun demikian, ini adalah masalah c # .