如果我将一个不实现Equals和GetHashCode的键对象放入一个字典中,那么字典的ContainsKey如何工作?它会检查引用是否相等吗?
谢谢。
谢谢。
Object
类实现了 Equals 和 GetHashCode。所有类默认都继承自 Object
。字典将只使用这些实现。Equals
来验证对象的身份。这样做效率不高,但可以正常工作。
因此,如果你想要更高的效率,应该考虑重写 GetHashCode,但如果只是一个小型字典且效率不是很重要,那么只需使用默认值即可。
[所有通常的注意事项仍然适用。最好不要为可变对象重写 GetHashCode,并确保对于返回 true 的 Equals() 对象返回相同的哈希码。]
它使用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();
}
}
GetHashCode()
函数时,您应该小心。如果它基于对象内容生成哈希码,并且这些内容是可变的,那么您可能会失去字典元素。这就是为什么您应该真正喜欢使用不可变类型作为字典键的另一个卓越建议。这是 Bill Wagners 的《Effective C#》中的另一条优秀建议 - 第7项:首选不可变原子值类型。 - Mark Booth
GetHashCode
方法对于不同的对象返回的哈希值不唯一并不妨碍在字典中使用它。最常见的键类型可能是string
,但很明显没有一种GetHashCode
函数可以将每个可能的字符串值映射到唯一的uint
值上。 - Daniel Earwicker