Apa perbedaan antara const
dan readonly
di C#?
Ketika anda akan menggunakan salah satu dari yang lain?
Terlepas dari perbedaan yang jelas dari
const
VS readonly
nilai-nilai yang dapat dihitung secara dinamis tetapi perlu diberikan sebelum konstruktor keluar.. setelah itu beku.statis
. Anda menggunakan ClassName.ConstantName
notasi untuk mengaksesnya.Ada perbedaan yang halus. Pertimbangkan kelas didefinisikan dalam AssemblyA
.
public class Const_V_Readonly
{
public const int I_CONST_VALUE = 2;
public readonly int I_RO_VALUE;
public Const_V_Readonly()
{
I_RO_VALUE = 3;
}
}
AssemblyB
referensi AssemblyA
dan menggunakan nilai-nilai ini dalam kode. Saat ini dikompilasi,
const
nilai, itu seperti menemukan-ganti, nilai 2 adalah 'dipanggang ke' yang AssemblyB
's IL. Ini berarti bahwa jika besok aku'll update I_CONST_VALUE
ke 20 di masa depan. AssemblyB
masih akan memiliki 2 sampai saya ulang ini.readonly
nilai, itu seperti ref
ke lokasi memori. Nilai ini tidak dipanggang menjadi AssemblyB
's IL. Ini berarti bahwa jika lokasi memori diperbarui, AssemblyB
mendapat nilai baru tanpa kompilasi ulang. Jadi jika I_RO_VALUE
ini diperbarui ke 30, anda hanya perlu membangun AssemblyA
. Semua klien tidak perlu dikompilasi ulang.Jadi jika anda yakin bahwa nilai konstan won't perubahan menggunakan const
.
public const int CM_IN_A_METER = 100;
Tapi jika anda memiliki konstan yang dapat berubah (misalnya w.r.t. presisi).. atau jika ragu, gunakan readonly
.
public readonly float PI = 3.14;
Update: Aku perlu mendapatkan lagi coz dia menunjuk ini keluar pertama. Aku juga perlu untuk plug di mana saya belajar ini.. Efektif C# - Bill Wagner
Ada gotcha dengan consts! Jika anda referensi konstan dari majelis lain, nilainya akan disusun tepat ke panggilan majelis. Dengan cara itu ketika anda memperbarui konstan di majelis direferensikan itu tidak't perubahan memanggil majelis!
Hanya untuk menambahkan, Dibaca untuk referensi jenis hanya membuat referensi readonly bukan nilai-nilai. Misalnya:
public class Const_V_Readonly
{
public const int I_CONST_VALUE = 2;
public readonly char[] I_RO_VALUE = new Char[]{'a', 'b', 'c'};
public UpdateReadonly()
{
I_RO_VALUE[0] = 'V'; //perfectly legal and will update the value
I_RO_VALUE = new char[]{'V'}; //will cause compiler error
}
}
Ini menjelaskan ini. Ringkasan: const harus diinisialisasi pada waktu deklarasi, readonly dapat diinisialisasi pada konstruktor (dan dengan demikian memiliki nilai yang berbeda tergantung pada constructor yang digunakan).
EDIT: Lihat Gishu's blog diatas untuk perbedaan halus
Ada yang kecil gotcha dengan readonly. Properti readonly lapangan dapat mengatur beberapa kali dalam constructor(s). Bahkan jika nilai diatur dalam dua berbeda dirantai konstruktor itu masih diperbolehkan.
public class Contoh {
pribadi readonly string ro;
public Sample() {
ro = "set";
}
public Sample(string value) : this() {
ro = value; // this works even though it was set in the no-arg ctor
}
}
Konstan anggota didefinisikan pada waktu kompilasi dan tidak dapat diubah saat runtime. Konstanta adalah dideklarasikan sebagai sebuah bidang, menggunakan const
kata kunci dan harus diinisialisasi seperti yang mereka nyatakan.
public class MyClass
{
public const double PI1 = 3.14159;
}
A readonly
anggota adalah seperti yang konstan dalam hal itu merupakan tidak berubah nilai. Perbedaannya adalah bahwa readonly
anggota dapat diinisialisasi pada saat runtime, dalam constructor, dan juga mampu untuk dapat diinisialisasi seperti yang mereka nyatakan.
public class MyClass1
{
public readonly double PI2 = 3.14159;
//or
public readonly double PI3;
public MyClass2()
{
PI3 = 3.14159;
}
}
const
statis
(mereka yang secara implisit statis)readonly
Const adalah compile-time konstan sedangkan readonly memungkinkan suatu nilai yang akan dihitung pada saat run-time dan ditetapkan dalam konstruktor atau bidang initializer. Jadi, 'const' selalu konstan tetapi 'readonly' read-only setelah itu ditugaskan.
Eric Lippert C# tim memiliki informasi lebih lanjut tentang berbagai jenis ketetapan
Di sini's link lain menunjukkan bagaimana const isn't versi aman, atau yang relevan untuk jenis referensi.
Ringkasan:
Belum lagi gotcha: readonly nilai-nilai yang dapat diubah oleh "licik" kode melalui refleksi.
var fi = this.GetType()
.BaseType
.GetField("_someField",
BindingFlags.Instance | BindingFlags.NonPublic);
fi.SetValue(this, 1);
Saya bisa mengubah pribadi readonly mewarisi lapangan di C# menggunakan refleksi?
Salah satu anggota tim di kantor kami memberikan panduan berikut pada saat menggunakan const, statis, dan readonly:
Satu catatan terakhir: const bidang statis, tetapi kebalikannya tidak benar.
Mereka berdua konstan, tetapi const tersedia juga pada waktu kompilasi. Ini berarti bahwa salah satu aspek dari perbedaan ini adalah bahwa anda dapat menggunakan const variabel sebagai masukan untuk atribut konstruktor, tapi tidak readonly variabel.
Contoh:
public static class Text {
public const string ConstDescription = "This can be used.";
public readonly static string ReadonlyDescription = "Cannot be used.";
}
public class Foo
{
[Description(Text.ConstDescription)]
public int BarThatBuilds {
{ get; set; }
}
[Description(Text.ReadOnlyDescription)]
public int BarThatDoesNotBuild {
{ get; set; }
}
}
Variabel ditandai const adalah sedikit lebih dari strongly typed #mendefinisikan macro, pada waktu kompilasi const variabel referensi diganti dengan inline nilai literal. Sebagai konsekuensi tertentu saja built-in primitif nilai jenis dapat digunakan dalam cara ini. Variabel ditandai readonly dapat diatur, dalam constructor, pada saat run-time dan mereka hanya-baca-ness diberlakukan selama run-time juga. Ada beberapa minor kinerja biaya yang terkait dengan hal ini, tetapi itu berarti anda dapat menggunakan readonly dengan jenis apa pun (bahkan jenis referensi).
Juga, const variabel pada dasarnya bersifat statis, sedangkan readonly variabel dapat menjadi contoh tertentu jika diinginkan.
Ada perbedaan penting antara const dan readonly di bidang C#.Net
const adalah secara default statis dan perlu diinisialisasi dengan nilai konstan, yang tidak dapat dimodifikasi di kemudian hari. Perubahan nilai yang tidak diperbolehkan dalam konstruktor, terlalu. Hal ini tidak dapat digunakan dengan semua tipe data. Untuk mantan - DateTime. Hal ini tidak dapat digunakan dengan DateTime datatype.
public const DateTime dt = DateTime.Today; //throws compilation error
public const string Name = string.Empty; //throws compilation error
public readonly string Name = string.Empty; //No error, legal
readonly dapat dinyatakan sebagai statis, tetapi tidak diperlukan. Tidak perlu menginisialisasi pada saat deklarasi. Nilainya dapat ditentukan atau diubah menggunakan konstruktor. Jadi, ini memberikan keuntungan ketika digunakan sebagai contoh anggota kelas. Dua yang berbeda instansiasi mungkin memiliki nilai yang berbeda dari kolom baca saja. Untuk mantan -
class A
{
public readonly int Id;
public A(int i)
{
Id = i;
}
}
Kemudian readonly lapangan dapat dijalankan dengan instan-nilai tertentu, sebagai berikut:
A objOne = new A(5);
A objTwo = new A(10);
Di sini, contoh objOne akan memiliki nilai readonly lapangan 5 dan objTwo memiliki 10. Yang tidak mungkin menggunakan const.
Lain gotcha.
Sejak const benar-benar hanya bekerja dengan tipe data dasar, jika anda ingin bekerja dengan sebuah kelas, anda mungkin merasa "memaksa" untuk menggunakan ReadOnly. Namun, waspadalah terhadap perangkap! ReadOnly berarti bahwa anda tidak dapat mengganti obyek dengan obyek yang lain (anda dapat't membuat merujuk ke objek lain). Tetapi setiap proses yang memiliki referensi ke objek adalah gratis untuk memodifikasi nilai-nilai dalam objek!
Jadi don't menjadi bingung berpikir bahwa ReadOnly berarti pengguna dapat't mengubah hal-hal. Tidak ada sintaks sederhana di C# untuk mencegah instansiasi dari suatu kelas mempunyai nilai-nilai internal berubah (sejauh yang saya tahu).
Konstanta
Kita perlu untuk memberikan nilai ke const lapangan ketika itu didefinisikan. Compiler kemudian menyimpan konstan nilai dalam perakitan metadata. Ini berarti bahwa yang konstan dapat didefinisikan hanya untuk tipe primitif seperti boolean, char, byte, dan sebagainya. Konstanta selalu dianggap statis anggota, bukan contoh anggota.
Readonly
Readonly bidang hanya dapat diselesaikan pada saat runtime. Itu berarti kita dapat menentukan nilai untuk nilai menggunakan constructor untuk tipe di mana bidang ini dinyatakan. Verifikasi ini dilakukan oleh compiler yang readonly bidang yang tidak tertulis oleh setiap metode lain dari konstruktor.
Lebih lanjut tentang kedua dijelaskan di sini dalam artikel ini