Це неправильне рішення, дивіться внизу.
Для тих, хто все ще використовує .NET 4.0 або раніше, у мене є клас, який працює так само, як і у прийнятій відповіді, але він набагато коротший. Він розширює існуючий об’єкт словника, перекриваючи (фактично приховуючи) певних членів, щоб вони викидали виняток, коли викликаються.
Якщо абонент намагається зателефонувати Додати, Видалити або якусь іншу мутаційну операцію, яку має вбудований словник, компілятор видасть помилку. Я використовую застарілі атрибути, щоб підняти ці помилки компілятора. Таким чином, ви можете замінити словник цим ReadOnlyDictionary і відразу побачити, де можуть виникнути проблеми, не запускаючи додаток і не чекаючи винятків під час виконання.
Поглянь:
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(); }
}
Це рішення має проблему, яку вказав @supercat, проілюстрований тут:
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);
}
Замість того, щоб дати помилку часу компіляції, як я очікував, або виняток із виконання, як я сподівався, цей код працює без помилок. Він друкує чотири числа. Це робить мій ReadOnlyDictionary ReadWriteDictionary.