Pertanyaan Apa perbedaan antara const dan readonly?


Apa perbedaan antara const dan readonly dan apakah Anda menggunakan salah satu dari yang lain?


989
2017-09-11 08:02


asal


Jawaban:


Terlepas dari perbedaan yang nyata

  • harus menyatakan nilai pada saat definisi untuk const VS readonly nilai dapat dihitung secara dinamis tetapi perlu ditetapkan sebelum konstruktor keluar .. setelah itu dibekukan.
  • 'Konst secara implisit static. Anda menggunakan ClassName.ConstantName notasi untuk mengaksesnya.

Ada perbedaan yang halus. Pertimbangkan kelas yang 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. Ketika ini dikompilasi,

  • dalam hal ini const nilai, itu seperti mencari-ganti, nilai 2 adalah 'dipanggang menjadi' AssemblyBIL. Ini berarti bahwa jika besok saya akan memperbarui I_CONST_VALUE sampai 20 di masa depan. AssemblyB masih memiliki 2 sampai saya mengkompilasi ulang.
  • dalam hal ini readonly nilai, itu seperti ref ke lokasi memori. Nilai tidak dimasukkan ke dalam AssemblyBIL. Ini berarti bahwa jika lokasi memori diperbarui, AssemblyB mendapat nilai baru tanpa rekompilasi. Jadi jika I_RO_VALUE diperbarui menjadi 30, Anda hanya perlu membangun AssemblyA. Semua klien tidak perlu dikompilasi ulang.

Jadi jika Anda yakin bahwa nilai konstanta tidak akan berubah, gunakan a const.

public const int CM_IN_A_METER = 100;

Tetapi jika Anda memiliki konstanta yang dapat berubah (misalnya w.r.t. presisi) .. atau ketika ragu, gunakan a readonly.

public readonly float PI = 3.14;

Perbarui: Aku perlu mendapatkan menyebutkan karena dia menunjukkan ini dulu. Saya juga perlu memasang di tempat saya belajar ini .. Efektif C # - Bill Wagner


979
2017-09-11 08:24



Ada gotcha dengan consts! Jika Anda mereferensikan konstanta dari rakitan lain, nilainya akan dikompilasi langsung ke rakitan panggilan. Dengan begitu ketika Anda memperbarui konstanta dalam rakitan yang direferensikan itu tidak akan berubah dalam perakitan panggilan!


237
2017-09-11 08:15



Konstanta

  • Konstanta statis secara default
  • Mereka harus memiliki nilai pada waktu kompilasi (Anda dapat memiliki misalnya 3.14 * 2, tetapi tidak dapat memanggil metode)
  • Bisa dinyatakan dalam fungsi
  • Disalin ke setiap majelis yang menggunakan mereka (setiap perakitan mendapat salinan nilai lokal)
  • Dapat digunakan dalam atribut

Bidang contoh hanya baca

  • Harus memiliki nilai yang ditetapkan, pada saat konstruktor keluar
  • Dievaluasi saat instance dibuat

Bidang hanya baca statis

  • Dievaluasi ketika eksekusi kode mencapai referensi kelas (ketika instance baru dibuat atau metode statis dijalankan)
  • Harus memiliki nilai yang dievaluasi pada saat konstruktor statis dilakukan
  • Ini tidak direkomendasikan untuk menempatkan ThreadStaticAttribute pada ini (konstruktor statis akan dieksekusi dalam satu utas saja dan akan mengatur nilai utasnya; semua utas lainnya akan memiliki nilai yang tidak diinisialisasi)

125
2017-12-02 11:50



Hanya untuk menambahkan, ReadOnly untuk tipe referensi hanya membuat referensi hanya baca bukan nilai. Sebagai contoh:

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

48
2017-09-11 10:37



Ini menjelaskannya. Ringkasan: const harus diinisialisasi pada waktu deklarasi, readonly dapat diinisialisasi pada konstruktor (dan dengan demikian memiliki nilai yang berbeda tergantung pada konstruktor yang digunakan).

EDIT: Lihat Gotcha Gishu di atas untuk perbedaan halus


37
2017-09-11 08:04



const: Tidak dapat diubah di mana saja.

readonly: Nilai ini hanya dapat diubah di konstruktor. Tidak dapat diubah dalam fungsi normal.


25
2018-05-21 13:21



Ada gotcha kecil dengan hanya bisa dibaca. Bidang hanya baca dapat diatur beberapa kali dalam konstruktor (s). Bahkan jika nilainya diatur dalam dua konstruktor berantai yang berbeda masih diperbolehkan.


public class Sample {
    private 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
    }
}

20
2017-10-19 22:14



Suatu const adalah konstanta waktu kompilasi sedangkan hanya membolehkan suatu nilai dihitung pada waktu-run dan diatur dalam konstruktor atau penginisialisasi lapangan. Jadi, 'const' selalu konstan tetapi 'readonly' hanya bisa dibaca setelah ditetapkan.

Eric Lippert tim C # memiliki lebih banyak informasi tentang berbagai jenis kekekalan


19
2017-09-11 08:07



Anggota konstan didefinisikan pada waktu kompilasi dan tidak dapat diubah saat runtime. Konstanta dideklarasikan sebagai bidang, menggunakan const kata kunci dan harus diinisialisasi saat mereka dideklarasikan.

public class MyClass
{
    public const double PI1 = 3.14159;
}

SEBUAH readonly anggotanya seperti konstan karena merupakan nilai yang tidak berubah. Perbedaannya adalah bahwa a readonly anggota dapat diinisialisasi pada saat runtime, di konstruktor, serta dapat diinisialisasi saat mereka dideklarasikan.

public class MyClass1
{
     public readonly double PI2 = 3.14159;

     //or

     public readonly double PI3;

     public MyClass2()
     {
         PI3 = 3.14159;
     }
}

const

  • Mereka tidak bisa dideklarasikan sebagai static (Mereka secara implisit statis)
  • Nilai konstanta dievaluasi pada waktu kompilasi
  • konstanta diinisialisasi hanya pada deklarasi

hanya bisa dibaca

  • Mereka bisa berupa tingkat-instance atau statis
  • Nilai dievaluasi pada waktu proses
  • readonly dapat diinisialisasi dalam deklarasi atau dengan kode di konstruktor

19
2017-09-17 11:48



Ini tautan lain menunjukkan bagaimana const bukan versi yang aman, atau relevan untuk tipe referensi.

Ringkasan:

  • Nilai properti const Anda diatur pada waktu kompilasi dan tidak dapat berubah saat runtime
  • Const tidak dapat ditandai sebagai statis - kata kunci menunjukkan mereka statis, tidak seperti bidang hanya baca yang bisa.
  • Const tidak bisa apa-apa kecuali jenis nilai (primitif)
  • Kata kunci hanya-baca menandai bidang sebagai tidak dapat diubah. Namun properti dapat diubah di dalam konstruktor kelas
  • Kata kunci hanya baca juga dapat dikombinasikan dengan statis untuk membuatnya bertindak dengan cara yang sama seperti const (minimal permukaan). Ada perbedaan yang mencolok ketika Anda melihat IL di antara keduanya
  • bidang const ditandai sebagai "literal" dalam IL sementara hanya "initonly"

14
2018-01-31 11:42



Namun gotcha yang lain: nilai baca dapat diubah dengan kode "licik" melalui refleksi.

var fi = this.GetType()
             .BaseType
             .GetField("_someField", 
                       BindingFlags.Instance | BindingFlags.NonPublic);
fi.SetValue(this, 1);

Dapatkah saya mengubah bidang warisan baca pribadi di C # menggunakan refleksi?


8
2017-10-13 02:26