ren*_*ene 4 c# overriding gethashcode
我有一些类,如下所示,我已经实现了Equals(Object)几乎所有的方法.但我不知道怎么写 GetHashCode().到目前为止,我在Dictionary集合中使用这些数据类型作为值类型,我想我应该覆盖GetHashCode().
我不知道如何GetHashCode()用逻辑来实现Equals(Object).
2.有一些派生类,如果我覆盖GetHashCode()并且Equals(Object)对于基类(Param),是否仍然需要为子节点覆盖它?
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;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑: 我得到这个警告:
警告:'Item'重写Object.Equals(object o)但不覆盖Object.GetHashCode()
kaj*_*kaj 14
首先,正如我认为您理解的那样,无论您在何处实施,Equals您都必须实施GetHashCode.实现GetHashCode必须反映实现的行为,Equals但通常不会使用它.
请参阅http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx - 尤其是"对实施者的说明"
所以,如果你把你的例子Item的实现Equals,你考虑两者的价值id和name影响平等.所以这些都必须有助于GetHashCode实施.
你如何执行的一个例子GetHashCode为Item将遵循以下的行(请注意您可能需要使其弹性为可空name字段):
public override GetHashCode()
{
return id.GetHashCode() ^ name.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)
请参阅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) ...
Run Code Online (Sandbox Code Playgroud)
我更喜欢乔什布洛赫的方法.
这是该Param课程的示例.
override GetHashCode(object obj)
{
unchecked
{
int hash = 17;
hash = hash * 23 + id.GetHashCode();
hash = hash * 23 + name.GetHashCode();
return hash;
}
}
Run Code Online (Sandbox Code Playgroud)
另外,请检查此链接:.net - GetHashCode的最佳算法用于 哈希码计算的属性也应该是不可变的.
| 归档时间: |
|
| 查看次数: |
20850 次 |
| 最近记录: |