我已经绞尽脑汁想了几个小时了,还是不明白碰撞到底是什么?
当两个不同的对象得到相同的哈希码时是这样吗?或者是当两个不同的对象进入字典数组中的同一个桶(位置)时?
还是别的原因
static Dictionary<Number, string> dict = new Dictionary<Number, string>();
class Number
{
private int X;
public Number(int x)
{
X = x;
}
public override bool Equals(object obj)
{
Number other = obj as Number;
return X.Equals(other.X);
}
public override int GetHashCode()
{
return X;
}
}
public static void Main(string[] args)
{
dict.Add(new Number(5), "Value5");
dict.Add(new Number(2), "Value2");
dict.Add(new Number(5), "Value52");
}
为什么这里的链接不起作用?
2条答案
按热度按时间8zzbczxx1#
还是不明白碰撞到底是什么?当两个不同的对象得到相同的哈希码时是这样吗?还是当两个不同的对象进入Dictionary数组中的同一个桶(位置)时?
哈希码冲突是指两个不同的对象获得相同的哈希码。不过没关系当
Equals
返回true
时,哈希码必须相等,但如果Equals
返回false
,即使GetHashCode
返回相同的值(冲突情况),也是可以的。此外,当两个哈希码不同时,对象不可能相等,所以Equals
必须返回false
。这都是关于规则的。但出于性能原因,它们应该分布良好,因此要避免太多(错误)冲突。
在您的示例中,您得到了一个
ArgumentException
,因为您使用X=5
添加了两个数字,这是在GetHashCode
和Equals
中检查的唯一属性。不能向字典添加重复的键。为什么这里的链接不起作用?
只有当方法返回您已修改的示例时,才可以链接多个调用,在本例中是字典。但是
Add
是一个void
方法,所以它什么也不返回。但是你也可以使用collection initializer:
当然,这会导致同样的异常,因为您添加了两个相同的键。
vh0rcniy2#
链接不起作用,因为
Add
方法返回void。它应该被设计为返回字典本身的一个示例,以便链接工作。我也认为这会很有用。