Dies ist eine schlechte Lösung, siehe unten.
Für diejenigen, die noch .NET 4.0 oder früher verwenden, habe ich eine Klasse, die genau wie die in der akzeptierten Antwort funktioniert, aber viel kürzer ist. Es erweitert das vorhandene Dictionary-Objekt und überschreibt (tatsächlich versteckt) bestimmte Mitglieder, damit sie beim Aufruf eine Ausnahme auslösen.
Wenn der Aufrufer versucht, Add, Remove oder eine andere Mutationsoperation des integrierten Wörterbuchs aufzurufen, gibt der Compiler einen Fehler aus. Ich verwende die veralteten Attribute, um diese Compilerfehler auszulösen. Auf diese Weise können Sie ein Wörterbuch durch dieses ReadOnlyDictionary ersetzen und sofort erkennen, wo Probleme auftreten können, ohne Ihre Anwendung ausführen und auf Laufzeitausnahmen warten zu müssen.
Schau mal:
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(); }
}
Diese Lösung weist ein Problem auf, auf das @supercat hier hinweist:
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);
}
Anstatt wie erwartet einen Fehler bei der Kompilierung oder eine von mir erhoffte Laufzeitausnahme anzugeben, wird dieser Code fehlerfrei ausgeführt. Es werden vier Zahlen gedruckt. Das macht mein ReadOnlyDictionary zu einem ReadWriteDictionary.