GetHashCode Equals implementation for a class in C#

ぃ、小莉子 提交于 2019-12-11 20:38:42

问题


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

回答1:


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.




回答2:


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: someone@website.com

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

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

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.




回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/4128584/gethashcode-equals-implementation-for-a-class-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!