Kei*_*ith 17 c# extension-methods dictionary keynotfoundexception
我发现自己有很多小烦恼 - 我有一个Dictionary<TKey, TValue>包含值可能存在或不存在的值.
所以正常的行为是使用索引器,如下所示:
object result = myDictionary["key"];
Run Code Online (Sandbox Code Playgroud)
但是,如果"key"不在字典中,则抛出a KeyNotFoundException,所以你这样做:
object val;
if (!myDictionary.TryGetValue("key", out val))
{
val = ifNotFound;
}
Run Code Online (Sandbox Code Playgroud)
哪个好,除了我可以连续加载这些 - 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;
}
Run Code Online (Sandbox Code Playgroud)
这让我做:
object result = myDictionary.TryGet("key1") ?? ifNotFound;
int i = anotherDictionary.TryGet("key2", -1);
Run Code Online (Sandbox Code Playgroud)
这很简单,但是名称类似于现有实例方法的附加扩展方法可能会增加混淆并降低可维护性.它也与字典的索引器集不一致 - 它将处理丢失的密钥.
所以选项2是一个新的实现,IDictionary<TKey, TValue>带有隐式转换,Dictionary<TKey, TValue>但是索引器返回default(TValue)而不是抛出a KeyNotFoundException.
那让我做:
ForgivingDictionary<string, object> dict = myDictionary;
object val = dict["key"] ?? ifNotFound;
// do stuff to val, then...
dict["key"] = val;
Run Code Online (Sandbox Code Playgroud)
所以现在get和set值是一致的,但值类型更混乱,ForgivingDictionary涉及更多代码.
这两种方法看起来都很"混乱" - 在.Net中有更好的方法吗?
这两种方法都会造成可能导致混淆的妥协,但是比另一种方法更明显/更明确吗?为什么?
在命名一个旨在替换现有方法的扩展方法时,我倾向于在方法名称中添加特异性而不是缩短它:
GetValueOrDefault(...)
Run Code Online (Sandbox Code Playgroud)
至于ForgivingDictionary,你可以约束TKey,使它不能是一个值类型.但是,如果您必须处理其中的值类型,那么您将返回值类型的内容,并且最好的选择是返回,default(TKey)因为您无法返回null.
老实说,我会使用扩展方法.
编辑:GetValueOrDefault()当然,如果找不到密钥,就不会添加到字典中.如果没有找到,我会返回一个默认值,因为它是如何命名的.如果有人想要插入它,那么一个好名字就是GetValueOrInsertDefault().
| 归档时间: |
|
| 查看次数: |
4525 次 |
| 最近记录: |