Usei o encapsulamento para criar um IDictionary com comportamento muito semelhante a um mapa STL , para aqueles que estão familiarizados com c ++. Para quem não é:
- O indexador get {} no SafeDictionary abaixo retorna o valor padrão se uma chave não estiver presente e adiciona essa chave ao dicionário com um valor padrão. Esse é geralmente o comportamento desejado, pois você procura itens que aparecerão eventualmente ou que têm uma boa chance de aparecer.
- O método Add (chave TK, TV val) se comporta como um método AddOrUpdate, substituindo o valor presente, se existir, em vez de jogar. Não vejo por que m $ não possui um método AddOrUpdate e acha que lançar erros em cenários muito comuns é uma boa ideia.
TL / DR - O SafeDictionary é gravado de forma a nunca lançar exceções sob nenhuma circunstância, exceto em cenários perversos , como o computador ficar sem memória (ou pegando fogo). Isso é feito substituindo o comportamento Add with AddOrUpdate e retornando o padrão em vez de gerar NotFoundException no indexador.
Aqui está o código:
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();
}
}