c# - 如何使用覆盖 Equals() 的逻辑实现对 GetHashCode() 的覆盖

标签 c# overriding gethashcode

我有一些类如下,我已经为几乎所有类实现了 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,都必须同时实现 GetHashCodeGetHashCode 的实现必须反射(reflect) Equals 实现的行为,但它通常使用它。

参见 http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx - 特别是“实现者须知”

因此,如果您以 EqualsItem 实现为例,您将同时考虑 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/

相关文章:

javascript - Javascript 科学记数法覆盖

c# - 带有自定义类键的慢字典

c# - 使用 Caliburn.Micro 的单实例 WPF 应用程序

c# - WPF INotifyPropertyChanged 不更新数组属性?

javascript - Node 模块的方法重写

.net - 覆盖类/向 ListviewItem 添加属性 (vb.net)

c# - .Net HashSet 唯一性计算是否完全基于Hash Codes?

c# - DateTime.Now 是否有自己的 GetHashCode 实现来提供唯一的哈希值?

c# - 限制文本日志文件的好方法

c# - 没有行时如何处理 CopyToDataTable()?