我发现自己有一个小烦恼——我有一个Dictionary<TKey, TValue>
包含可能存在或不存在的值的值。
所以正常的行为是使用索引器,如下所示:
object result = myDictionary["key"];
但是,如果"key"
不在字典中,则会抛出 a KeyNotFoundException
,因此您可以这样做:
object val;
if (!myDictionary.TryGetValue("key", out val))
{
val = ifNotFound;
}
这很好,除了我可以连续加载这些 -TryGetValue
开始感觉非常笨重。
所以选项1是一种扩展方法:
public static TValue TryGet<TKey, TValue>(
this Dictionary<TKey, TValue> input,
TKey key,
TValue ifNotFound = default(TValue))
{
TValue val;
if (input.TryGetValue(key, out val))
{
return val;
}
return ifNotFound;
}
这让我可以:
object result = myDictionary.TryGet("key1") ?? ifNotFound;
int i = anotherDictionary.TryGet("key2", -1);
这很简单,但是名称类似于现有实例方法的附加扩展方法可能会增加混乱并降低可维护性。它也与字典的索引器集不一致 - 它将处理丢失的键。
所以选项 2 是一个新的实现,IDictionary<TKey, TValue>
它带有一个隐式转换,Dictionary<TKey, TValue>
但一个索引器返回default(TValue)
而不是抛出一个KeyNotFoundException
.
让我这样做:
ForgivingDictionary<string, object> dict = myDictionary;
object val = dict["key"] ?? ifNotFound;
// do stuff to val, then...
dict["key"] = val;
所以现在 get 和 set 的值是一致的,但是值类型比较混乱并且ForgivingDictionary
涉及到更多的代码。
这两种方法看起来都很“混乱”——.Net 中有没有更好的方法来做到这一点?
这两种方法都做出了可能导致混淆的妥协,但一种比另一种更明显/清晰吗?为什么?