簡體   English   中英

GetHashCode等於C#中的類的實現

[英]GetHashCode Equals implementation for a class in C#

我有一個Person類,必須重寫Equals和GetHashCode方法。 如果名稱匹配或電子郵件匹配,則兩個人對象相等。 用相當有效的哈希函數執行此操作的好方法是什么?

class Person
{
    string Name
    string Email

    public override Equals(object obj)
    {
        if (ReferenceEquals(obj, null))
            return false;
        if (ReferenceEquals(this, obj))
            return true;
        if (obj is Person)
        {
            Person person = (Person)obj;
            return
                (this.Name == person.Name)
                || (this.Email == person.Email);
        }
        return false;
    }

    public override GetHashCode()
    {
        // What's a good way to implement?
    }
}

你不能,真的。 好吧,除了返回常量值之外。

這樣看吧...所有擁有電子郵件“ x”的人都必須具有相同的哈希碼,因為它們是相等的。 並且所有名稱為“ y”的人都必須具有相同的哈希碼,因此它繼續進行:

Name    Email    Hash
  n1       e1      h1
  n2       e1      h1 (because emails are equal
  n2       e2      h1 (because names are equal to previous)

請注意,我們如何設法將名稱電子郵件都更改為任意值,但哈希值仍必須為h1。

我知道這不能回答您的問題,但是您的方法不正確。 可以預期,如果a == b和b == c,則必然遵循a == c。

Person a:
    name: mike
    email: someone@website.com

Person b:
    name: steve
    email: someone@website.com

Person c:
    name: steve
    email: steve@website.com

在此示例中,a == b,b == c,但是a!= c。 這是不正確的行為。 如果要實現此行為,則最好使用Equals以外的方法進行此比較,但不等於。

請參閱http://msdn.microsoft.com/zh-cn/library/ms173147%28VS.80%29.aspx

就像Alex所說的,這更多是與業務規則相關的事情,我不會為此目的使用Equals。 我還有另一種方法可以實現您在Equals方法中的實現。

當然,Alex提到了Name + email的哈希,但是自從Jon指出以來,這對您都不起作用,考慮到您擁有的業務規則,這實際上不是您可以做的。

有一種方法可以執行您要嘗試執行的操作。

假設您有一個這樣定義的枚舉

public enum MatchedOn { None, Name, Email }

接下來,將Equals方法的實現拉到另一個方法中,以便從Equals方法中調用它。 在這種新方法中,如果名稱相等,則將枚舉設置為Name;如果電子郵件相等,則將枚舉設置為Email;如果兩者相同,則將None設置為None。

然后,在GetHashCode實現中,您也可以調用此新方法,然后基於Name或Email或兩者的組合返回哈希碼。

我希望這是有道理的。

暫無
暫無

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

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