是否有一个IDictionary的实现,在丢失的键,返回默认值,而不是抛出?
如果关键字丢失,Dictionary中的索引器将引发exception。 是否有一个IDictionary的实现,而不是将返回默认(T)?
我知道“TryGetValue”方法,但这是不可能与linq一起使用的。
这会有效地做我需要的东西吗?
myDict.FirstOrDefault(a => a.Key == someKeyKalue);
我不认为这将会迭代键而不是使用散列查找。
事实上,这根本不会有效。
你总是可以写一个扩展方法:
public static TValue GetValueOrDefault<TKey,TValue> (this IDictionary<TKey, TValue> dictionary, TKey key) { TValue ret; // Ignore return value dictionary.TryGetValue(key, out ret); return ret; }
进行这些扩展方法可以帮助..
public static V GetValueOrDefault<K, V>(this IDictionary<K, V> dict, K key) { return dict.GetValueOrDefault(key, default(V)); } public static V GetValueOrDefault<K, V>(this IDictionary<K, V> dict, K key, V defVal) { return dict.GetValueOrDefault(key, () => defVal); } public static V GetValueOrDefault<K, V>(this IDictionary<K, V> dict, K key, Func<V> defValSelector) { V value; return dict.TryGetValue(key, out value) ? value : defValSelector(); }
人们可以为字典的键查找function定义一个接口。 我可能将其定义为如下所示:
Interface IKeyLookup(Of Out TValue) Function Contains(Key As Object) Function GetValueIfExists(Key As Object) As TValue Function GetValueIfExists(Key As Object, ByRef Succeeded As Boolean) As TValue End Interface Interface IKeyLookup(Of In TKey, Out TValue) Inherits IKeyLookup(Of Out TValue) Function Contains(Key As TKey) Function GetValue(Key As TKey) As TValue Function GetValueIfExists(Key As TKey) As TValue Function GetValueIfExists(Key As TKey, ByRef Succeeded As Boolean) As TValue End Interface
具有非通用键的版本将允许使用非结构键types的代码的代码允许任意键变化,这对于genericstypes参数是不可能的。 一个不应该被允许使用可变Dictionary(Of Cat, String)
作为可变Dictionary(Of Animal, String)
因为后者将允许SomeDictionaryOfCat.Add(FionaTheFish, "Fiona")
。 但是,使用一个可变的Dictionary(Of Cat, String)
作为一个不可变的Dictionary(Of Animal, String)
没有什么错,因为SomeDictionaryOfCat.Contains(FionaTheFish)
应该被认为是一个完美的格式expression式(它应该返回false
,search字典,任何不是types的Cat
)。
不幸的是,一个人能够实际使用这种接口的唯一方法就是在一个实现接口的类中包装一个Dictionary
对象。 然而,根据你在做什么,这样一个接口和它允许的变化可能会使得值得付出努力。
Collections.Specialized.StringDictionary
在查找缺less的键值时提供了一个非例外的结果。 这也是默认情况下不区分大小写的。
注意事项
它只适用于其专业用途,而且 – 在generics之前devise – 如果您需要查看整个集合,则不具有很好的枚举器。
如果您正在使用ASP.NET MVC,则可以利用执行此工作的RouteValueDictionary类。
public object this[string key] { get { object obj; this.TryGetValue(key, out obj); return obj; } set { this._dictionary[key] = value; } }
那么这个单线程检查使用ContainsKey
是否存在一个键,然后使用条件运算符返回正常的retreived值或默认值呢?
var myValue = myDictionary.ContainsKey(myKey) ? myDictionary[myKey] : myDefaultValue;
不需要实现一个支持默认值的新的Dictionary类,只需用上面的短行代替你的查询语句即可。
public class DefaultIndexerDictionary<TKey, TValue> : IDictionary<TKey, TValue> { private IDictionary<TKey, TValue> _dict = new Dictionary<TKey, TValue>(); public TValue this[TKey key] { get { TValue val; if (!TryGetValue(key, out val)) return default(TValue); return val; } set { _dict[key] = value; } } public ICollection<TKey> Keys => _dict.Keys; public ICollection<TValue> Values => _dict.Values; public int Count => _dict.Count; public bool IsReadOnly => _dict.IsReadOnly; public void Add(TKey key, TValue value) { _dict.Add(key, value); } public void Add(KeyValuePair<TKey, TValue> item) { _dict.Add(item); } public void Clear() { _dict.Clear(); } public bool Contains(KeyValuePair<TKey, TValue> item) { return _dict.Contains(item); } public bool ContainsKey(TKey key) { return _dict.ContainsKey(key); } public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) { _dict.CopyTo(array, arrayIndex); } public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() { return _dict.GetEnumerator(); } public bool Remove(TKey key) { return _dict.Remove(key); } public bool Remove(KeyValuePair<TKey, TValue> item) { return _dict.Remove(item); } public bool TryGetValue(TKey key, out TValue value) { return _dict.TryGetValue(key, out value); } IEnumerator IEnumerable.GetEnumerator() { return _dict.GetEnumerator(); } }
下面是C#7.1世界中的@ JonSkeet的一个版本,它还允许传递一个可选的默认值:
public static TV GetValueOrDefault<TK, TV>(this IDictionary<TK, TV> dict, TK key, TV defaultValue = default) => dict.TryGetValue(key, out TV value) ? value : defaultValue;
不,因为否则当密钥存在但是存储空值时,你会怎么知道这个差别? 这可能是重大的。