如果我使用Hashtable
,我可以编写如下代码:
object item = hashtable[key] ?? default_value;
无论key
中是否显示Hashtable
,
Dictionary<TKey. TValue>
我无法做到这一点。如果密钥不在字典中,则会抛出KeyNotFoundException
。所以我必须编写这样的代码:
MyClass item;
if (!(dict.TryGetValue(key, out item))
{
item = default_value;
}
我想知道为什么会这样。 Dictionary<TKey, TValue>
只是Hashtable
的封套。为什么要添加此限制?
修改
关于PopCatalin的答案的另一个观点(见下文),如果字典的值是值类型,我上面写的代码将不起作用。如果我使用Dictionary<int, int>
,那么我将喜欢使用的代码如下所示:
int i = dict[key] ?? default_value;
这不会编译,因为dict[key]
不是可空或引用类型。
答案 0 :(得分:8)
Dictionary<T>
和Hashtable
之间的区别在于Dictionary<T>
是一种通用类型,可以专门用于在引用类型中存储值类型。
哈希表只能存储引用类型(引用传递的Object
)和仅存储的值类型(也通过引用传递)。
当字典专门用于值类型时,它必须“按值”返回这些值而不是通过引用。因此,Dictionary<T>
不能返回null,因为null 不是有效的价值类型的价值。
答案 1 :(得分:4)
你的帖子中有一个误解。字典不是Hashtable的包装器。这是一个完全不同的实现。
进行此更改的原因主要是由一个断言证明:Null是哈希表的有效值。如果没有此更改,则无法使用[]访问方法区分非外生键和值为null的值键。字典清除了这一点。
答案 2 :(得分:2)
我为此写了一个扩展名。
public static class DictionaryExtension
{
public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> items, string key)
{
if (items != null && items.ContainsKey(key))
{
return items[key];
}
return default(TValue);
}
}
答案 3 :(得分:1)
如果您使用Reflector查看代码,您会看到Dictionary尝试查找密钥,显式 如果找不到密钥则会引发异常。
public TValue get_Item(TKey key)
{
int index = this.FindEntry(key);
if (index >= 0)
{
return this.entries[index].value;
}
ThrowHelper.ThrowKeyNotFoundException();
return default(TValue);
}
答案 4 :(得分:1)
Dictionary.ContainsKey可能比TryGetValue更好。
但至于为什么,不知道。
答案 5 :(得分:0)
我很确定这个限制是首先创建包装器的功能原因之一。