Saya menggunakan enkapsulasi untuk membuat IDictionary dengan perilaku yang sangat mirip dengan peta STL , bagi Anda yang terbiasa dengan c ++. Bagi mereka yang tidak:
- indexer dapatkan {} di SafeDictionary di bawah ini mengembalikan nilai default jika kunci tidak ada, dan menambahkan kunci itu ke kamus dengan nilai default. Ini sering merupakan perilaku yang diinginkan, karena Anda mencari item yang nantinya akan muncul atau memiliki peluang bagus untuk muncul.
- metode Add (kunci TK, val TV) berperilaku sebagai metode AddOrUpdate, menggantikan nilai sekarang jika ada, bukan melempar. Saya tidak mengerti mengapa m $ tidak memiliki metode AddOrUpdate dan berpikir melempar kesalahan dalam skenario yang sangat umum adalah ide yang bagus.
TL / DR - SafeDictionary ditulis agar tidak pernah membuat pengecualian dalam keadaan apa pun, selain skenario sesat , seperti komputer kehabisan memori (atau terbakar). Ini dilakukan dengan mengganti Add dengan perilaku AddOrUpdate dan mengembalikan default alih-alih melempar NotFoundException dari pengindeks.
Berikut kodenya:
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();
}
}