我有一些类如下,我已经为几乎所有类实现了 Equals(Object)
方法。但我不知道如何编写 GetHashCode()
。就我在 Dictionary
集合中使用这些数据类型作为值类型而言,我认为我应该覆盖 GetHashCode()
。
1.我不知道如何用Equals(Object)
的逻辑实现GetHashCode()
。
2.有一些派生类,如果我为基类(Param
)覆盖GetHashCode()
和Equals(Object)
,是否仍然需要为 child 覆盖它?
class Param
{
...
public Int16 id { get; set; }
public String name { get; set; }
...
public override bool Equals(object obj)
{
if ( obj is Param){
Param p = (Param)(obj);
if (id > 0 && p.id > 0)
return (id == p.id);
else if (name != String.Empty && p.name != String.Empty)
return (name.equals(p.name));
else
return object.ReferenceEquals(this, obj);
}
return false;
}
}
class Item
{
public int it_code { get; set; }
public Dictionary<String, Param> paramAr { get; set; }
...
public override bool Equals(Object obj)
{
Item im = new Item();
if (obj is Item)
im = (Item)obj;
else
return false;
if (this.it_code != String.Empty && im.it_code != String.Empty)
if (this.it_code.Equals(im.it_code))
return true;
bool reParams = true;
foreach ( KeyValuePair<String,Param> kvp in paramAr ){
if (kvp.Value != im.paramAr[kvp.Key]) {
reParams = false;
break;
}
}
return reParams;
}
}
class Order
{
public String or_code { get; set; }
public List <Item> items { get; set; }
...
public override bool Equals( Object obj ){
Order o = new Order();
if (obj is Order)
o = (Order)obj;
else
return false;
if (this.or_code != String.Empty && o.or_code != String.Empty)
if (this.or_code.Equals(o.or_code))
return true;
bool flag = true;
foreach( Item i in items){
if (!o.items.Contains(i)) {
flag = false;
break;
}
}
return flag;
}
}
编辑: 我收到此警告:
Warning : 'Item' overrides Object.Equals(object o) but does not override Object.GetHashCode()
最佳答案
首先,正如我认为您理解的那样,无论您在何处实现 Equals
,都必须同时实现 GetHashCode
。 GetHashCode
的实现必须反射(reflect) Equals
实现的行为,但它通常使用它。
参见 http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx - 特别是“实现者须知”
因此,如果您以 Equals
的 Item
实现为例,您将同时考虑 id
和 的值name
来影响平等。因此,这两者都必须对 GetHashCode
的实现做出贡献。
如何为 Item
实现 GetHashCode
的示例如下(请注意,您可能需要使其对可为 null 的 具有弹性名称
字段):
public override GetHashCode()
{
return id.GetHashCode() ^ name.GetHashCode();
}
请参阅 Eric Lippert 关于 GetHashCode
指南的博客文章 - http://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/
至于您是否需要在子类中重新实现 GetHashCode
- 是的,如果您还覆盖 Equals
- 根据第一个(和主要)点 - 的实现两者必须一致 - 如果 Equals
认为两个项目相等,则它们必须从 GetHashCode
返回相同的值。
旁注: 作为代码的性能改进(避免多次转换):
if ( obj is Param){
Param p = (Param)(obj);
Param p = obj as Param;
if (p != null) ...
关于c# - 如何使用覆盖 Equals() 的逻辑实现对 GetHashCode() 的覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9827911/