wie man Accessor für Dictionary in einer Art und Weise zu machen, die zurückgegeben Wörterbuch kann nicht C # / 2.0 geändert werden
-
25-09-2019 - |
Frage
Ich dachte an Lösung unten, weil die Sammlung sehr sehr klein ist. Aber was, wenn es groß?
private Dictionary<string, OfTable> _folderData = new Dictionary<string, OfTable>();
public Dictionary<string, OfTable> FolderData
{
get { return new Dictionary<string,OfTable>(_folderData); }
}
Mit Liste Sie machen können:
public class MyClass
{
private List<int> _items = new List<int>();
public IList<int> Items
{
get { return _items.AsReadOnly(); }
}
}
Das wäre schön!
Vielen Dank im Voraus, Prost & BR - Matti
Jetzt, wenn ich denke OBJEKTE DER IN COLLECTION ARE IN HAUFEN. SO meine Lösung nicht daran hindert, den Aufrufer modifizieren !!! Ursache BEIDE Wörterbuch s enthalten Verweise auf gleiche Objekt. Gilt dies zur Liste Beispiel oben?
class OfTable
{
private int _table;
private List<int> _classes;
private string _label;
public OfTable()
{
_classes = new List<int>();
}
public int Table
{
get { return _table; }
set { _table = value; }
}
public List<int> Classes
{
get { return _classes; }
set { _classes = value; }
}
public string Label
{
get { return _label; }
set { _label = value; }
}
}
so, wie man diese unveränderlich ??
Lösung
Es ist nicht schwierig, Ihre eigene ReadOnlyDictionary<K,V>
Wrapper-Klasse zu rollen. So etwas wie folgt aus:
public sealed class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
private readonly IDictionary<TKey, TValue> _dictionary;
public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
{
if (dictionary == null)
throw new ArgumentNullException("dictionary");
_dictionary = dictionary;
}
public bool ContainsKey(TKey key)
{
return _dictionary.ContainsKey(key);
}
public int Count
{
get { return _dictionary.Count; }
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return _dictionary.GetEnumerator();
}
public ICollection<TKey> Keys
{
get { return _dictionary.Keys; }
}
public bool TryGetValue(TKey key, out TValue value)
{
return _dictionary.TryGetValue(key, out value);
}
public ICollection<TValue> Values
{
get { return _dictionary.Values; }
}
public TValue this[TKey key] // Item
{
get { return _dictionary[key]; }
}
#region IDictionary<TKey, TValue> Explicit Interface Implementation
void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
{
throw new NotSupportedException("Dictionary is read-only.");
}
bool IDictionary<TKey, TValue>.Remove(TKey key)
{
throw new NotSupportedException("Dictionary is read-only.");
}
TValue IDictionary<TKey, TValue>.this[TKey key] // Item
{
get { return _dictionary[key]; }
set { throw new NotSupportedException("Dictionary is read-only."); }
}
#endregion
#region ICollection<T> Explicit Interface Implementation
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
{
throw new NotSupportedException("Collection is read-only.");
}
void ICollection<KeyValuePair<TKey, TValue>>.Clear()
{
throw new NotSupportedException("Collection is read-only.");
}
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
{
return _dictionary.Contains(item);
}
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
_dictionary.CopyTo(array, arrayIndex);
}
bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
{
get { return true; }
}
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
{
throw new NotSupportedException("Collection is read-only.");
}
#endregion
#region IEnumerable Explicit Interface Implementation
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)_dictionary).GetEnumerator();
}
#endregion
}
Wenn Sie mit C # 3 oder höher, dann könnten Sie eine passende AsReadOnly
Erweiterungsmethode Knock-up zu:
public static class ReadOnlyDictionaryHelper
{
public static ReadOnlyDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
{
var temp = dictionary as ReadOnlyDictionary<TKey, TValue>;
return temp ?? new ReadOnlyDictionary<TKey, TValue>(dictionary);
}
}
Und dann kehrt die Nur-Lese-Wrapper aus Ihrer Immobilie:
// in C#2
return new ReadOnlyDictionary<string, OfTable>(_folderData);
// in C#3 or later
return _folderData.AsReadOnly();
Andere Tipps
Verwenden Sie ReadOnlyCollection<T>
Klasse.
Eine Instanz der Klasse Readonlycollection Gattungs ist immer schreibgeschützt. Eine Sammlung ist, die schreibgeschützt ist einfach eine Sammlung mit einem Wrapper, der verhindert, dass die Sammlung Modifizierung; Deshalb, wenn Änderungen an der zugrunde liegenden Auflistung vorgenommen werden, spiegelt die schreibgeschützte Auflistung jene Änderungen. Siehe Sammlung für eine veränderbare Version dieser Klasse.
- EDIT -
Zur Kasse eines trivial Wörterbuch Wrapper hier. Und A Allgemein Read-Only Wörterbuch von Richard Carr.