2008-12-04 86 views
1

我有一个Customer类。继承相等比较器

public class Customer 
{ 
    private string _id; 
    private string _name; 
    // some more properties follow 

我继承了EqualityComparer表单MyEqualityComparer(Customer)。
这我打算在LINQ查询中使用。
MyEqualityComparer用于在两个对象之间进行部分检查。
如果customer.id和customer.name匹配,我将对象视为相等。

public class MyComparer : System.Collections.Generic.EqualityComparer<Customer> 
{ 
    public override bool Equals(Customer x, Customer y) 
    { 
     if (x.Id == y.Id && x.Name == y.Name) 
      return true; 
     else 
      return false; 
    } 

    public override int GetHashCode(Customer obj) 
    { 
     return string.Concat(obj.Id,obj.Name).GetHashCode(); 
    } 

} 

我提到generating hashcode
我很不确定如何连接字符串并将其用作散列码。
这是安全的,我正在尝试做什么?

回答

5

一个相当简单的方法基于多个字段返回一个哈希码见this question on hashcodes。这样说,我不会从EqualityComparer<T>我自己得到 - 我只是直接实现了IEqualityComparer<T>。我不确定EqualityComparer<T>真的会给你带来什么价值,除了实施非通用IEqualityComparer

一对夫妇更多的事情:

  • 中值为
  • 您现在的Equals代码可以简化为您应该处理无效:

    return x.Id == y.Id && x.Name == y.Name; 
    

更全面执行的Equals的可能成为:

public override bool Equals(Customer x, Customer y) 
{ 
    if (object.ReferenceEquals(x, y)) 
    { 
     return true; 
    } 
    if (x == null || y == null) 
    { 
     return false; 
    } 
    return x.Id == y.Id && x.Name == y.Name; 
} 
+0

小错误 - 在与null比较之前,您需要将x和y转换为对象。请参阅http://msdn.microsoft.com/en-us/library/ms173147 – Thracx 2012-11-24 23:32:08

3

你应该从可能的“碰撞”的角度来看它,例如,当两个不同的对象获得相同的散列码时。对于“1,2any”和“12,any”这样的对,情况可能如此,对中的值是“id”和“name”。如果您的数据无法做到这一点,那么您很好。否则,你可以把它改成这样的:

return obj.Id.GetHashCode()^obj.Name.GetHashCode(); 
+0

不要忘记检查ID和名称 – 2008-12-04 13:13:19

+0

不幸的是,在很多情况下使用XOR会产生冲突。请参阅http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-systemobjectgethashcode#263416。在名称/ ID的情况下可能没问题,但总的来说这不是一个好主意。 – 2008-12-04 14:07:41

1

ReSharper的(从JetBrains的梦幻般的重构插件)认为它应该是:

public override int GetHashCode(Customer obj) 
{ 
    unchecked 
    { 
     return ((obj.Id != null ? obj.Id.GetHashCode() : 0) * 397) 
      ^(obj.Name != null ? obj.Name.GetHashCode() : 0); 
    } 
} 

我不得不承认,我几乎总是只让ReSharper的生成平等和哈希代码实现了我。我已经测试了他们的实现,并发现它与我手写的任何东西都不差。所以我通常会采用我不需要输入的实现。