会者不难的问题

xiaolei1982 2007-12-28 11:10:53
刚刚看了GetHashCode()方法,在网上也查过资料,但还是有这么几个不解:
首先如果我们重载了==方法,也要重写 Object.Equals(object o),重写了Equals就要重写GetHashCode(),
不理解这之间到底存在着什么联系必须要这样,之间是什么在互相影响呢
...全文
259 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
yhy0611 2007-12-29
  • 打赏
  • 举报
回复
学习
xiaolei1982 2007-12-28
  • 打赏
  • 举报
回复
还是没有头绪,这么问吧我重写了==,系统会提示我重写equal,
我可以用系统自带的重写,这时就不会提示了,可两者之间有什么联系必须要这样,
我==的重写有关于类和整形的比较,有该类和别的类的比较,
到底是什么意思啊,谢谢haiwangstar

michaelwangwh 2007-12-28
  • 打赏
  • 举报
回复
GetHashCode不应该这么实现吧?
haiwangstar 2007-12-28
  • 打赏
  • 举报
回复
你所说的相等指的是内容相等?? return this==x as car;
比较的是引用。要实现那样的比较,像string一样,要你自己写代码。
xiaolei1982 2007-12-28
  • 打赏
  • 举报
回复
我把我写的完整的省略掉

public override bool Equals(object x)
{
if (!(x is car))
{
return false;
}
else
{
return this==x as car;
}
}
public override int GetHashCode()
{
return base.GetHashCode();
}
if (acar.Equals(bcar))
{
Console.Write(acar.GetHashCode()+"----"+bcar.GetHashCode());
}

这样我重写了,并且也返回true,可两个对象的不相同啊
haiwangstar 2007-12-28
  • 打赏
  • 举报
回复
因为如果Object.Equals返回true,表示2个对象相等。这时GetHashCode也必须返回相等的数值。反之,亦然。如果只重写Equals,不重写GetHashCode,不是会产生矛盾了? 明白了?
ms44 2007-12-28
  • 打赏
  • 举报
回复
GetHashCode每个对象都不同。你EQUAL方法里会检查。
haiwangstar 2007-12-28
  • 打赏
  • 举报
回复
xiaolei1982 2007-12-28
  • 打赏
  • 举报
回复
哦对对,晕既然返回相等肯定是同一个类,哎呀糊涂了哈哈,
感谢haiwangstar ,我研究了一天,研究出这么点东西来,不知道值不值啊,哈哈感谢
xiaolei1982 2007-12-28
  • 打赏
  • 举报
回复
不过仔细看看好像没有这样操作啊,还是请haiwangstar 帮忙解答一下吧
haiwangstar 2007-12-28
  • 打赏
  • 举报
回复
A.Equals(B) 返回true 则A.GetHashCode()与B.GetHashCode()返回的散列码就应相等


没错。Point是一个很好的例子,两个Point如果Equals相等,那HASHCODE也一定相等。从源头上看,因为HASHCODE是用x,y计算得到的。所以如果两个Point如果值相等,则HASHCODE一定相等。

那它对比较的对象B作用在哪?没有改变B的GetHashCode()啊,怎么就相等了呢


不需要改变什么。。两个Point使用的都同一个Hash函数,而且是比较x,y. 所以x,y相等。那HASHCODE一定相等了。
xiaolei1982 2007-12-28
  • 打赏
  • 举报
回复
哦,晕了,应该是两个对象A,B都重写equal和GetHashCode()对吧,希望如此我就彻底
醒悟了
xiaolei1982 2007-12-28
  • 打赏
  • 举报
回复
研究了一下午最后一个问题了:请问haiwangstar
我看了我们常用来重写的gethashcode方法,


  public   struct   Point   {  
public int x;
public int y;

//other methods

public override int GetHashCode() {
return x ^ y;
}
}

A.Equals(B) 返回true 则A.GetHashCode()与B.GetHashCode()返回的散列码就应相等
那它对比较的对象B作用在哪?没有改变B的GetHashCode()啊,怎么就相等了呢
gengtao1120 2007-12-28
  • 打赏
  • 举报
回复
如果你不用散列表,就可以不用重写gethashcode方法了
lvxianda 2007-12-28
  • 打赏
  • 举报
回复
学习下
GhostAdai 2007-12-28
  • 打赏
  • 举报
回复
看Java编程思想里面对为什么重写了Equals就要重写GetHashCode的问题说的比较“清楚”(看得晕晕乎乎),看完了Java编程思想再转过头用C#你会发现只是不会用VS建工程而已,其他的基本诀窍都已经基本掌握了。
haiwangstar 2007-12-28
  • 打赏
  • 举报
回复
如果引用类型的语义是基于该类型表示某个(些)值的事实,则考虑对该类型重写 Equals。

即使大多数引用类型重写 ,它们也必须不能重载相等运算符。但是,如果实现的引用类型想要具有值语义(如复杂的数字类型),则必须重写相等运算符。


这是重载Equals的准则。看明白了吗,,就是说如果你想实现内容的比较,可以重写Equals,但一般不要重写==

关于HASH的准则是这样

如果两个类型相同的对象表示相同的值,则哈希函数必须为两个对象返回相同的常数值。

为了获得最佳性能,哈希函数必须为所有输入生成随机分布。

不论对该对象进行什么样的更改,哈希函数都必须返回完全相同的值。

看明白了吧,如果你的类是基于值语义的,也就是重载了Equals,来比较内容,则应该重写GetHashCode, 以返回相同的HASH值 。但实际上,如果你不需要用对象的GetHashCode来作为散列的键的话,可以不实现的。。直接用系统的实现就可以了。

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧