加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 19:51:10 所属栏目:百科 来源:网络整理
导读:我有一些类如下,我已经为几乎所有的类实现了Equals(Object)方法.但我不知道如何编写GetHashCode().到目前为止,我在Dictionary Collection中使用这些数据类型作为值类型,我想我应该重写GetHashCode(). 1.我不知道如何使用Equals(Object)逻辑实现GetHashCode()
我有一些类如下,我已经为几乎所有的类实现了Equals(Object)方法.但我不知道如何编写GetHashCode().到目前为止,我在Dictionary Collection中使用这些数据类型作为值类型,我想我应该重写GetHashCode().

1.我不知道如何使用Equals(Object)逻辑实现GetHashCode().

2.有一些派生类,如果我覆盖基类(Param)的GetHashCode()和Equals(Object),是否仍然需要为子项覆盖它?

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的实现必须反映Equals实现的行为,但通常不会使用它.

见http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx – 特别是“对实施者的说明”

因此,如果您以Equals的Item实现为例,您将考虑id和name的值来影响相等性.因此,这两者必须有助于GetHashCode实现.

您可以如何为Item实现GetHashCode的示例将如下所示(请注意,您可能需要使其具有对可空名称字段的弹性):

public override GetHashCode()
{
    return id.GetHashCode() ^ name.GetHashCode();
}

请参阅Eric Lippert关于GetHashCode指南的博客文章 – http://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/

至于你是否需要在子类中重新实现GetHashCode – 是的,如果你也重写等于 – 按照第一个(和主要的)点 – 两者的实现必须是一致的 – 如果两个项被认为等于等于那么它们必须从GetHashCode返回相同的值.

边注:
作为代码的性能改进(避免多次转换):

if ( obj is Param){
    Param p = (Param)(obj);

Param p = obj as Param;
if (p != null) ...

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读