Użyłem hermetyzacji, aby stworzyć IDictionary o zachowaniu bardzo podobnym do mapy STL , dla tych z Was, którzy znają c ++. Dla tych, którzy nie są:
- indeksator get {} w SafeDictionary poniżej zwraca wartość domyślną, jeśli nie ma klucza, i dodaje ten klucz do słownika z wartością domyślną. Jest to często pożądane zachowanie, ponieważ szukasz przedmiotów, które ostatecznie się pojawią lub mają dużą szansę na pojawienie się.
- metoda Add (klucz TK, wartość TV) zachowuje się jak metoda AddOrUpdate, zastępując wartość obecną, jeśli istnieje, zamiast rzucać. Nie rozumiem, dlaczego m $ nie ma metody AddOrUpdate i uważa, że rzucanie błędów w bardzo typowych scenariuszach jest dobrym pomysłem.
TL / DR - SafeDictionary jest napisany tak, aby nigdy nie zgłaszać wyjątków w żadnych okolicznościach, innych niż perwersyjne scenariusze , takie jak brak pamięci na komputerze (lub pożar). Robi to, zastępując Add zachowaniem AddOrUpdate i zwracając wartość default zamiast wyrzucania NotFoundException z indeksatora.
Oto kod:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public class SafeDictionary<TK, TD>: IDictionary<TK, TD> {
Dictionary<TK, TD> _underlying = new Dictionary<TK, TD>();
public ICollection<TK> Keys => _underlying.Keys;
public ICollection<TD> Values => _underlying.Values;
public int Count => _underlying.Count;
public bool IsReadOnly => false;
public TD this[TK index] {
get {
TD data;
if (_underlying.TryGetValue(index, out data)) {
return data;
}
_underlying[index] = default(TD);
return default(TD);
}
set {
_underlying[index] = value;
}
}
public void CopyTo(KeyValuePair<TK, TD>[] array, int arrayIndex) {
Array.Copy(_underlying.ToArray(), 0, array, arrayIndex,
Math.Min(array.Length - arrayIndex, _underlying.Count));
}
public void Add(TK key, TD value) {
_underlying[key] = value;
}
public void Add(KeyValuePair<TK, TD> item) {
_underlying[item.Key] = item.Value;
}
public void Clear() {
_underlying.Clear();
}
public bool Contains(KeyValuePair<TK, TD> item) {
return _underlying.Contains(item);
}
public bool ContainsKey(TK key) {
return _underlying.ContainsKey(key);
}
public IEnumerator<KeyValuePair<TK, TD>> GetEnumerator() {
return _underlying.GetEnumerator();
}
public bool Remove(TK key) {
return _underlying.Remove(key);
}
public bool Remove(KeyValuePair<TK, TD> item) {
return _underlying.Remove(item.Key);
}
public bool TryGetValue(TK key, out TD value) {
return _underlying.TryGetValue(key, out value);
}
IEnumerator IEnumerable.GetEnumerator() {
return _underlying.GetEnumerator();
}
}