繁体   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