代码之家  ›  专栏  ›  技术社区  ›  hIpPy

GetHashCode等于C中类的实现#

  •  0
  • hIpPy  · 技术社区  · 14 年前

    我有一个类人员,我必须重写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?
        }
    }
    
    4 回复  |  直到 12 年前
        1
  •  10
  •   Jon Skeet    14 年前

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

    往这边看…所有电子邮件为“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。

        2
  •  8
  •   snarf    14 年前

    我知道这不能回答你的问题,但你的方法是错误的。如果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.这是不正确的行为。如果您想要实现这个行为,那么有一个方法other等于这个比较,但不等于。

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

        3
  •  0
  •   Jackie Kirby    14 年前

    正如亚历克斯所说,这更像是一个与业务规则相关的事情,我不会为此使用equals。我还有另一个方法,它有您在equals方法中使用的实现。

    当然,Alex提到了一个名字+电子邮件的散列列表,但这对你也不起作用,因为Jon指出,考虑到你的业务规则,这并不是你真正能做的事情。

        4
  •  -4
  •   Shiv Kumar    14 年前

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

    假设您有一个这样定义的枚举

    public enum MatchedOn { None, Name, Email }
    

    接下来,将equals方法的实现拉到另一个方法中,这样就可以从equals方法调用它。在这个新方法中,如果名称相同,则将枚举设置为name;如果电子邮件相同,则将枚举设置为email;如果两者都不相同,则将枚举设置为none。

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

    我希望这是有道理的。