Я использовал инкапсуляцию для создания IDictionary с поведением, очень похожим на карту STL , для тех из вас, кто знаком с C ++. Для тех, у кого нет:
- indexer get {} в SafeDictionary ниже возвращает значение по умолчанию, если ключ отсутствует, и добавляет этот ключ в словарь со значением по умолчанию. Часто это желаемое поведение, поскольку вы ищете элементы, которые со временем появятся или имеют хорошие шансы появиться.
- метод Add (ключ TK, TV val) ведет себя как метод AddOrUpdate, заменяя существующее значение, если оно существует, вместо того, чтобы бросать. Я не понимаю, почему у m $ нет метода AddOrUpdate, и считает, что выдача ошибок в очень распространенных сценариях - хорошая идея.
TL / DR - SafeDictionary написан так, чтобы никогда не вызывать исключения ни при каких обстоятельствах, кроме извращенных сценариев. , таких как памяти (или пожар) компьютера. Для этого он заменяет Add на поведение AddOrUpdate и возвращает значение по умолчанию вместо выдачи NotFoundException из индексатора.
Вот код:
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();
}
}