C# 中类的 GetHashCode Equals 实现

发布于 2024-10-01 09:56:34 字数 670 浏览 3 评论 0原文

我有一个 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?
    }
}

I have a class Person for which I have to override the Equals and GetHashCode method. Two person objects are equals if the Name matches OR if the Email matches. What's a good way of doing this with a considerably efficient hash function?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我最亲爱的 2024-10-08 09:56:34

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

这样看...所有电子邮件地址为“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。

You can't, really. Well, not apart from returning a constant value.

Look at it this way... all people with email "x" have to have the same hash code, because they're equal. And all people with name "y" have to have the same hash code, and so it goes on:

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

Note how we've managed to change both the name and the email to arbitrary values, but the hash has to still be h1.

霊感 2024-10-08 09:56:34

我知道这并不能回答你的问题,但你的方法是不正确的。预计如果 a == b,且 b == c,则必然得出 a == c。

Person a:
    name: mike
    email: [email protected]

Person b:
    name: steve
    email: [email protected]

Person c:
    name: steve
    email: [email protected]

在此示例中,a == b,且 b == c,但 a != c。这是不正确的行为。如果您想实现此行为,最好使用 Equals 以外的方法来执行此比较,但不使用 equals。

请参阅 http://msdn.microsoft.com/en- us/library/ms173147%28VS.80%29.aspx

I know that this does not answer your question, but your approach is incorrect. It is expected that if a == b, and b == c, it necessarily follows that a == c.

Person a:
    name: mike
    email: [email protected]

Person b:
    name: steve
    email: [email protected]

Person c:
    name: steve
    email: [email protected]

In this example a == b, and b == c, but a != c. This is incorrect behavior. If you want to implement this behavior, it is perfectly fine to have a method other that Equals that does this comparison, but not equals.

See http://msdn.microsoft.com/en-us/library/ms173147%28VS.80%29.aspx.

当梦初醒 2024-10-08 09:56:34

正如 Alex 所说,这更多的是与业务规则相关的事情,我不会为此目的使用 Equals。我有另一种方法,它具有 Equals 方法中的实现。

当然,亚历克斯提到了姓名+电子邮件的散列,但这对您来说也不起作用,因为乔恩指出,考虑到您拥有的业务规则,这实际上并不是您可以做的事情。

Like Alex said, this is more of a business rule related thing and I wouldn't use Equals for this purpose. I'd have another method that has the implementation you have in the Equals method.

Of course, Alex mentions a hash of Name+email but that won't work for you either since Jon pointed out, it's not really something you can do given the business rules you have.

望喜 2024-10-08 09:56:34

有一种方法可以让你做你想做的事。

假设您有一个像这样定义的 Enum

public enum MatchedOn { None, Name, Email }

接下来,将 Equals 方法的实现拉出到另一个方法中,以便从 Equals 方法中调用它。在此新方法中,如果名称相等,则将枚举设置为 Name;如果电子邮件相等,则将枚举设置为 Email;如果两者不相同,则将枚举设置为 None。

然后,在 GetHashCode 实现中,您也可以调用这个新方法,然后根据名称或电子邮件或两者的组合返回哈希代码。

我希望这是有道理的。

There is a way in which you can do what you're trying to do.

Let's say you have an Enum that you've defined like so

public enum MatchedOn { None, Name, Email }

Next, pull out the implementation of your Equals method into another method such that you call it from your Equals method. In this new method, set the enum to be Name if the names are equal or Email if the emails are equal or None if neither is the same.

Then in your GetHashCode implementation you can call this new method as well and then return a hashed code based on Name or Email or the combination of both.

I hope that makes sense.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文