簡體   English   中英

如何使用覆蓋的邏輯Equals()實現GetHashCode()的覆蓋

[英]how to implement override of GetHashCode() with logic of overriden Equals()

我有一些類如下,我已經為幾乎所有的類實現了Equals(Object)方法。 但我不知道如何編寫GetHashCode() 到目前為止,我在Dictionary Collection中使用這些數據類型作為值類型,我想我應該重寫GetHashCode()

1.我不知道如何使用Equals(Object)邏輯實現GetHashCode() Equals(Object)

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;
    }
}

編輯:我得到這個警告:

警告:'Item'重寫Object.Equals(object o)但不覆蓋Object.GetHashCode()

首先,正如我所知,無論你在哪里實現Equals你都必須實現GetHashCode GetHashCode的實現必須反映Equals實現的行為,但通常不會使用它。

請參閱http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx - 尤其是“對實施者的說明”

因此,如果您以EqualsItem實現為例,您將考慮idname的值來影響相等性。 因此,這兩者必須有助於GetHashCode實現。

您可以如何為Item實現GetHashCode的示例將如下所示(請注意,您可能需要使其具有對可空name字段的彈性):

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) ...

我更喜歡喬什布洛赫的方法。

這是Param類的示例。

override GetHashCode(object obj)
{
 unchecked
    {
        int hash = 17;

        hash = hash * 23 + id.GetHashCode();
        hash = hash * 23 + name.GetHashCode();
        return hash;
    }
}

另外,請檢查此鏈接: .net - GetHashCode的最佳算法用於哈希碼計算的屬性也應該是不可變的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM