Ini adalah solusi yang buruk, lihat di bagian bawah.
Bagi mereka yang masih menggunakan .NET 4.0 atau sebelumnya, saya memiliki kelas yang berfungsi seperti yang ada di jawaban yang diterima, tetapi jauh lebih pendek. Itu memperluas objek Kamus yang ada, menimpa (sebenarnya menyembunyikan) anggota tertentu agar mereka melemparkan pengecualian saat dipanggil.
Jika pemanggil mencoba memanggil Tambah, Hapus, atau operasi mutasi lain yang dimiliki Kamus bawaan, kompiler akan membuat kesalahan. Saya menggunakan atribut Usang untuk meningkatkan kesalahan kompilator ini. Dengan cara ini, Anda dapat mengganti Kamus dengan ReadOnlyDictionary ini dan segera melihat di mana masalah mungkin tanpa harus menjalankan aplikasi Anda dan menunggu pengecualian run-time.
Lihatlah:
public class ReadOnlyException : Exception
{
}
public class ReadOnlyDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
: base(dictionary) { }
public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
: base(dictionary, comparer) { }
//The following four constructors don't make sense for a read-only dictionary
[Obsolete("Not Supported for ReadOnlyDictionaries", true)]
public ReadOnlyDictionary() { throw new ReadOnlyException(); }
[Obsolete("Not Supported for ReadOnlyDictionaries", true)]
public ReadOnlyDictionary(IEqualityComparer<TKey> comparer) { throw new ReadOnlyException(); }
[Obsolete("Not Supported for ReadOnlyDictionaries", true)]
public ReadOnlyDictionary(int capacity) { throw new ReadOnlyException(); }
[Obsolete("Not Supported for ReadOnlyDictionaries", true)]
public ReadOnlyDictionary(int capacity, IEqualityComparer<TKey> comparer) { throw new ReadOnlyException(); }
//Use hiding to override the behavior of the following four members
public new TValue this[TKey key]
{
get { return base[key]; }
//The lack of a set accessor hides the Dictionary.this[] setter
}
[Obsolete("Not Supported for ReadOnlyDictionaries", true)]
public new void Add(TKey key, TValue value) { throw new ReadOnlyException(); }
[Obsolete("Not Supported for ReadOnlyDictionaries", true)]
public new void Clear() { throw new ReadOnlyException(); }
[Obsolete("Not Supported for ReadOnlyDictionaries", true)]
public new bool Remove(TKey key) { throw new ReadOnlyException(); }
}
Solusi ini memiliki masalah yang ditunjukkan oleh @supercat yang diilustrasikan di sini:
var dict = new Dictionary<int, string>
{
{ 1, "one" },
{ 2, "two" },
{ 3, "three" },
};
var rodict = new ReadOnlyDictionary<int, string>(dict);
var rwdict = rodict as Dictionary<int, string>;
rwdict.Add(4, "four");
foreach (var item in rodict)
{
Console.WriteLine("{0}, {1}", item.Key, item.Value);
}
Daripada memberikan kesalahan waktu kompilasi seperti yang saya harapkan, atau pengecualian runtime seperti yang saya harapkan, kode ini berjalan tanpa kesalahan. Mencetak empat angka. Itu membuat ReadOnlyDictionary saya menjadi ReadWriteDictionary.