为什么Dictionary不像Hashtable那样访问不存在的键呢?

时间:2008-12-30 01:19:20

标签: c# .net dictionary hashtable

如果我使用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]不是可空或引用类型。

6 个答案:

答案 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)

我很确定这个限制是首先创建包装器的功能原因之一。