在某些情况下,当字典中没有这样的键时,对于我来说,有一个简短的,可读的方式来获取null而不是KeyNotFoundException按键访问字典值,这似乎是有用的.
我想到的第一件事是扩展方法:
public static U GetValueByKeyOrNull<T, U>(this Dictionary<T, U> dict, T key)
where U : class //it's acceptable for me to have this constraint
{
if (dict.ContainsKey(key))
return dict[key];
else
//it could be default(U) to use without U class constraint
//however, I didn't need this.
return null;
}
Run Code Online (Sandbox Code Playgroud)
但是当你写下这样的东西时,它实际上并不是很短暂的说法:
string.Format("{0}:{1};{2}:{3}",
dict.GetValueByKeyOrNull("key1"),
dict.GetValueByKeyOrNull("key2"),
dict.GetValueByKeyOrNull("key3"),
dict.GetValueByKeyOrNull("key4"));
Run Code Online (Sandbox Code Playgroud)
我会说,有一些接近基本语法的东西要好得多:dict["key4"].
然后我想出了一个带有private字典字段的类的想法,它暴露了我需要的功能:
public class MyDictionary<T, U> //here I may add any of interfaces, implemented
//by dictionary itself to get an opportunity to,
//say, use foreach, etc. and implement them
// using the dictionary field.
where U : class
{
private Dictionary<T, U> dict;
public MyDictionary()
{
dict = new Dictionary<T, U>();
}
public U this[T key]
{
get
{
if (dict.ContainsKey(key))
return dict[key];
else
return null;
}
set
{
dict[key] = value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,基本行为的微小变化似乎有点开销.
还有一种解决方法可能是Func在当前上下文中定义a ,如下所示:
Func<string, string> GetDictValueByKeyOrNull = (key) =>
{
if (dict.ContainsKey(key))
return dict[key];
else
return null;
};
Run Code Online (Sandbox Code Playgroud)
所以可以像GetDictValueByKeyOrNull("key1").
请你再给我一些建议或帮助选择一个更好的建议?
Jar*_*d G 55
这是我个人库中的解决方案,作为扩展方法实现.我只发布它,因为它是从字典界面实现的,并允许传入可选的默认值.
履行
public static TV GetValue<TK, TV>(this IDictionary<TK, TV> dict, TK key, TV defaultValue = default(TV))
{
TV value;
return dict.TryGetValue(key, out value) ? value : defaultValue;
}
Run Code Online (Sandbox Code Playgroud)
用法
MyDictionary.GetValue("key1");
MyDictionary.GetValue("key2", -1);
MyDictionary.GetValue("key3")?.SomeMethod();
Run Code Online (Sandbox Code Playgroud)
bmm*_*m6o 31
您无法使用扩展方法获得所需的语法,并且正如其他人所说,重写方法/运算符以更改其行为通常不是一个好主意.我认为你能做的最好就是缩短你使用的名字.
那就是你需要保持IDictionary界面.如果您没有与任何需要IDictionary的代码连接,那么您可以自由定义自己的界面并让[]运算符以不同的方式工作不是问题.
无论你最终调用该函数,你都希望像这样实现它:
public static U Get<T, U>(this Dictionary<T, U> dict, T key)
where U : class
{
U val;
dict.TryGetValue(key, out val);
return val;
}
Run Code Online (Sandbox Code Playgroud)
它只执行一次查找,而实现则只执行2次查找.
hor*_*rgh 22
最后,我想出了一个使用从字典类派生并使用显式接口实现的变体:
public interface INullValueDictionary<T, U>
where U : class
{
U this[T key] { get; }
}
public class NullValueDictionary<T, U> : Dictionary<T, U>, INullValueDictionary<T, U>
where U : class
{
U INullValueDictionary<T, U>.this[T key]
{
get
{
U val;
dict.TryGet(key, out val);
return val;
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此它以下列方式公开了我需要的功能:
//create some dictionary
NullValueDictionary<int, string> dict = new NullValueDictionary<int, string>
{
{1,"one"}
};
//have a reference to the interface
INullValueDictionary<int, string> idict = dict;
try
{
//this throws an exception, as the base class implementation is utilized
Console.WriteLine(dict[2] ?? "null");
}
catch { }
//this prints null, as the explicit interface implementation
//in the derived class is used
Console.WriteLine(idict[2] ?? "null");
Run Code Online (Sandbox Code Playgroud)
Tim*_*ang 10
添加DictionaryExtension类
public static class DictionaryExtension
{
public static TValue GetValueOrDefault<TKey, TValue>
( this IDictionary<TKey, TValue> dictionary,TKey key)
{
TValue value;
return dictionary.TryGetValue(key, out value) ? value : default(TValue);
}
}
Run Code Online (Sandbox Code Playgroud)
如果在字典中找不到键,它可以返回默认值.
如果这是引用类型,则Default为null.
_dic.GetValueOrDefault();
Run Code Online (Sandbox Code Playgroud)
值得指出的是HybridDictionary默认情况下会这样做。您失去了泛型类型,但获得了 null-if-not-found 功能。
我认为(至少在理论上)您可以在少量值时获得性能优势。
我前提是我不会使用它。该new关键字,而在这种情况下非常有用,可以创建错误,这些错误是真的很难找到。除此之外,您可以尝试此类。
class MyDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
public new TValue this[TKey key]
{
get
{
TValue value;
return TryGetValue(key, out value) ? value : default(TValue);
}
set { base[key] = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
50743 次 |
| 最近记录: |