代码之家  ›  专栏  ›  技术社区  ›  Robert Rossney

为什么字典不能像哈希表那样访问不存在的键?

  •  5
  • Robert Rossney  · 技术社区  · 16 年前

    如果我用的是 Hashtable ,我可以这样编写代码:

    object item = hashtable[key] ?? default_value;
    

    不管是否有效 key 出现在 哈希表 .

    我不能用 Dictionary<TKey. TValue> . 如果字典中没有该键,则将引发 KeyNotFoundException . 所以我必须写这样的代码:

    MyClass item;
    if (!(dict.TryGetValue(key, out item))
    {
       item = default_value;
    }
    

    我想知道这是为什么。 Dictionary<TKey, TValue> 只是包装纸 哈希表 . 为什么要增加这个限制?

    编辑:

    对于另一个关于popcatalin答案的观点(见下文),如果字典中的值是值类型,那么我上面写的代码将不起作用。如果我用的是 Dictionary<int, int> ,那么代码我会 喜欢 要使用,请如下所示:

    int i = dict[key] ?? default_value;
    

    这不会编译,因为 dict[key] 不是可以为空的或引用类型。

    6 回复  |  直到 16 年前
        1
  •  8
  •   Pop Catalin    16 年前

    两者之间的区别 Dictionary<T> 和A Hashtable 那是 字典<t> 是一个通用类型,可以专门化以沿引用类型存储值类型。

    哈希表只能存储引用类型(A Object 通过引用传递)并且仅限于装箱的值类型(也通过引用传递)。

    当字典专门化值类型时,它必须“按值”而不是通过引用返回这些值。 字典<t> 不能返回空值,因为空值为 不是有效值 对于值类型。

        2
  •  4
  •   JaredPar    16 年前

    在你的文章中有一个误解。字典不是哈希表的包装。这是一个完全不同的实现。

    进行此更改的原因主要由一个断言来证明:空是哈希表的有效值。如果不进行此更改,则无法使用访问的[]方法区分不存在的键和具有空值的值键。字典会把这个清除掉。

        3
  •  2
  •   Mike Geise    16 年前

    我为此写了一个扩展名。

    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);
        }
    }
    
        4
  •  1
  •   Otávio Décio    16 年前

    如果您使用Reflector查找代码,您将看到字典试图查找键和 明确地 如果找不到键,则引发异常。

    public TValue get_Item(TKey key)
    {
        int index = this.FindEntry(key);
        if (index >= 0)
        {
            return this.entries[index].value;
        }
        ThrowHelper.ThrowKeyNotFoundException();
        return default(TValue);
    }
    
        5
  •  1
  •   Sekhat    16 年前

    dictionary.containsKey可能比TryGetValue更适合您。

    但至于原因,不知道。

        6
  •  0
  •   Sparr    16 年前

    我非常肯定,这种限制首先是创建包装器的功能原因之一。