大家帮忙看看这个HashCode怎么写?

zengjd 2009-10-22 11:12:19

class Entire
{
public string Name
{
get {return _name;}
set { _name =value ;}
}private string _name = "";
public List<Part> Parts
{
get { return _Parts; }
set { _Parts = value; }
}private List<Part> _Parts = null;
public override int GetHashCode()
{
//这个HashCode应该怎么写? }
public override bool Equals(object obj)
{
if ( ( obj as Entire ) == null)
return false;
return this.GetHashCode== obj.GetHashCode();
}
}

...全文
269 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
微创社(MCC) 2009-10-25
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 zengjd 的回复:]
引用 6 楼 pcnetman888 的回复:
Equals不应该依赖于HASHCODE

Name.GetHashCode()足够用了



这里的Name不是唯一的,可以重复!
[/Quote]

Hashcode并不要求唯一,要求足够分散。
Name己经足够用的。
zengjd 2009-10-22
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 lzhdim 的回复:]
对象判断是托管堆上的数据判断。而值判断是栈上的判断。两个是有区别的。
[/Quote]

我这里需要的是值判断!
你不会说Class不能利用值判断两个对象是否相等吧?
lzhdim 2009-10-22
  • 打赏
  • 举报
回复
对象判断是托管堆上的数据判断。而值判断是栈上的判断。两个是有区别的。
lzhdim 2009-10-22
  • 打赏
  • 举报
回复
还有就是 深复制和阴影复制 的问题,你搞搞清楚。。。
lzhdim 2009-10-22
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 zengjd 的回复:]
引用 9 楼 lzhdim 的回复:
Equals写错了,改改:
public override bool Equals(object obj)
        {
            if(!(obj is Entire))
            {
              return false;
            }
            else
            {
                return this == (Entire)obj;
            }
        }


  HashCOde先不说。
你的相等判断的好像不对。
只判断了引用是否相等,
值相等怎么判断呢?

[/Quote]


拜托,你这个是class,判断的是类型。值相等直接判断即可 ...........
  • 打赏
  • 举报
回复
只要两对象Equals返回true,这两个对象的GetHashCode()必须相等.反之,当两个对象的GetHashCode()相等时,这两个对象的Equals返回可以不是true,它只是会影响hashset等数据结构的效率.


zengjd 2009-10-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 lzhdim 的回复:]
Equals写错了,改改:
public override bool Equals(object obj)
        {
            if(!(obj is Entire))
            {
              return false;
            }
            else
            {
                return this == (Entire)obj;
            }
        }
[/Quote]

HashCOde先不说。
你的相等判断的好像不对。
只判断了引用是否相等,
值相等怎么判断呢?
lzhdim 2009-10-22
  • 打赏
  • 举报
回复
Equals写错了,改改:
public override bool Equals(object obj)
{
if(!(obj is Entire))
{
return false;
}
else
{
return this == (Entire)obj;
}
}
lzhdim 2009-10-22
  • 打赏
  • 举报
回复
Equals本身就是根据hashcode来判断对象是否对等的。

Equals这样写:
public override bool Equals(object obj)
{
if(!(obj is Name))
{
return false;
}
else
{
return this == (Name)obj;
}
}

GetHashCode这样写:
public override int GetHashCode()
{
return this.Name.GetHashCode() + this.Parts.GetHashCode();
}


要给分啊。。。。。。。。
zengjd 2009-10-22
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 pcnetman888 的回复:]
Equals不应该依赖于HASHCODE

Name.GetHashCode()足够用了

[/Quote]

这里的Name不是唯一的,可以重复!
微创社(MCC) 2009-10-22
  • 打赏
  • 举报
回复
Equals不应该依赖于HASHCODE

Name.GetHashCode()足够用了
zengjd 2009-10-22
  • 打赏
  • 举报
回复
有没有人知道啊?
cc_net 2009-10-22
  • 打赏
  • 举报
回复
Name.GetHashCode() ^ Parts.GetHashCode()

不知道,哈哈
zengjd 2009-10-22
  • 打赏
  • 举报
回复
怎么没有高人指点啊
zengjd 2009-10-22
  • 打赏
  • 举报
回复
大家帮忙啊!
zengjd 2009-10-22
  • 打赏
  • 举报
回复
Part类可以实现自己的HashCode
zengjd 2009-10-22
  • 打赏
  • 举报
回复
怎么没有高人了?
zengjd 2009-10-22
  • 打赏
  • 举报
回复
从代码上看,也是一个无限递归!
zengjd 2009-10-22
  • 打赏
  • 举报
回复
运行下这段代码试试。
结果不对。

class Car
{
public string carname = "";
public string cartype = "";

//重写Equals方法
public override bool Equals(object obj)
{
//判断this不能为null
if (obj == null)
return false;
//类型不样 也是不能相等的
if (this.GetType() != obj.GetType())
{
return false;
}
//前面已经判断这个对象是相等的 所以他们不会编译报错的
Car car = (Car)obj;
//对其引用类型字段比较
if (!Object.Equals(this, car))
{
return false;
}
return true;
//return base.Equals(obj);
}
}


static void Main(string[] args)
{

Car car1 = new Car();
car1.carname = "a";
car1.cartype = "b";

Car car2 = new Car();
car2.carname = "c";
car2.cartype = "d";

bool isequal = car1.Equals(car2);
isequal = object.Equals(car1, car2);
}
lzhdim 2009-10-22
  • 打赏
  • 举报
回复
C#中的类型相等与恒等问题。

CLR提供了可以区分类型的Equality 和Identity能力。

l Equality:如果两个对象是相同的类型,并且它们各自带有相同和等值的属性。(They are instances of the same type and if each of the fields in one object matches the values of the fields in the other object)
Equality必须满足三个必要条件:reflexive, symmetrics, and transitive
reflexive: 自身相等,及a==a 是永远成立的;
symmetrics: 对象性,及a==b成立那么b==a 也成立;
transitive: 传递性,及a==b, b==c成立那么a==c 也成立。

l Identity:两个对象必须相等(意味着他们共享同一块内存区域)(The two objects have the same values. – Two objects are identical if they share an address in memory)

CLR提供了至少四种方法来判断两个对象的等价性:

1. Public static bool ReferenceEquals(object left, object right);

2. Public static bool Equals(object left, object right);
3. Public virtual bool Equals(object right);
4. Public static bool operator==(MyClass left, MyClass right);

ReferenceEquals方法总是用来判断两个对象的Identity的,不管是针对值类型还是引用类型。所以针对值类型,调用该方法总是会返回false,因为值类型作为这个方法的参数时会进行装箱操作。

静态的Equals方法提供了判断两个对象的Equality能力,在其实现的内部,调用了上述第三个虚拟的Equals方法。和ReferenceEquals一样,它们已经具备从底层判断两个对象的能力,我们从来不会覆写这两个方法。

实例Equals方法也是用来区分两个对象的Equality的。

l 对于引用类型的对象,它和ReferenceEquals方法几乎是一样的。(因为判断两个引用类型是否的Equality往往从Identity上就可以区分)

l 而值类型的对象,我们不仅要判断他们具有相同的对象类型,还要判断他们的值相等。值类型从System.ValueType继承而来,ValueType 已经重写了Object.Equals()方法,本来已经可以用来满足这些要求的。但是ValueType.Equals()方法不是很有效,因为它必须要通过反射,在不知道具体的派生类型中,完成对它们所含有成员变量的值的比较。因此,建议在我们实现一个值类型的数据结构时,同时重写ValueType.Equals()方法。
l 然而我们再回头看看引用类型,有时两个引用类型的对象往往被用来进行类似值类型的比较,比如:String类型,它虽然是引用类型,但它也重写了 Equals方法,因为我们拿它来判断两个string是否相同(Equality),实际是希望判断它们是否具有相同的内容,这是一个value semantics。因此,我们建议在考虑实现一个用作值语义环境下的引用类型时候,也重写基类的Object.Equals()方法。

注:请参考MDSN或其它相关文档,如何实现Equals方法的重写。

==运算符是可由类重载的运算符,它也是用来判断恒等的。
对于未重载==的引用类型,会比较两个引用类型是否引用同一个对象。这跟引用类型的Equals()方法是一样的。

对于未重载==的值类型,该运算符会比较这两个值是否"按位"相等,即是否这两个值中的每个字段都相等。和Equals方法一样,推荐在自定义值类型中,也要重载==运算符,因为也存在反射在效率上的影响。

==运算符和Equals方法的区别在于多态表现上。Equals方法是重写,而==运算符是被重载。这意味着除非编译器知道调用具体的重载版本,否则它只是调用未重载的==版本。
加载更多回复(14)

110,536

社区成员

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

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

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