繁体   English   中英

Dictionary <T>如何处理未实现Equals和GetHashCode的关键对象?

[英]How does Dictionary<T> work with key objects that don't implement Equals and GetHashCode?

如果我将一个关键对象放在一个没有实现Equals和GetHashCode的Dictionary中,那么Dictionary ContainsKey是如何工作的? 通过检查引用是否相等?

谢谢

基类Object类实现EqualsGetHashCode 默认情况下,所有类都从Object继承。 字典将只使用这些实现。

Equals测试对象引用的默认实现,在大多数情况下对于您的字典可能会很好。

GetHashCode的基本实现相当幼稚,事实上甚至文档都说明:

GetHashCode方法的默认实现不保证不同对象的唯一返回值。

因此,如果您打算将对象用作字典或散列表键,建议您自己覆盖它。

关于它是如何工作的。 请记住,GetHashCode实际上对于字典的实现并不重要。 哈希码允许冲突,这就是重点。 哈希代码仅用于帮助定位对象,是否用于检查对象到底是否正确的相等性测试。 让我们说,为了论证,每个对象只返回一个哈希码1.它们都会在字典中的同一个底池中结束,可能是以一些相当随机的顺序(可能是插入的顺序)而且它会回落到使用Equals验证对象标识。 它效率不高,但效果很好。

因此,如果您正在寻找效率,您应该考虑覆盖GetHashCode,但如果它只是一个小字典并且效率不是太重要,那么您可以将它保留为默认值。

[所有通常的考虑因素都适用。 最好不要为可变对象重写GetHashCode,并且100%确保为Equals()返回true的对象返回相同的哈希码。

它使用Object.GetHashCode实现,但请注意,此哈希代码不是对象标识:

GetHashCode方法的默认实现不保证不同对象的唯一返回值。 此外,.NET Framework不保证GetHashCode方法的默认实现,并且它返回的值在不同版本的.NET Framework之间是相同的。 因此,此方法的默认实现不得用作散列目的的唯一对象标识符。

如果要让字典对引用相等进行操作,则可以在构造字典时使用以下比较器:

class ReferenceComparer<T> : IEqualityComparer<T>
{
    public bool Equals(T x, T y)
    {
        return object.ReferenceEquals(x, y);
    }

    public int GetHashCode(T obj)
    {
        return obj.GetHashCode();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM