English 中文(简体)
继承相等比较器
原标题:
  • 时间:2008-12-04 13:02:47
  •  标签:

我有一个顾客类。

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

I am inheriting the EqualityComparer form MyEqualityComparer(of Customer).
This I am intending to use in LINQ queries.
MyEqualityComparer is intended for partial check between two objects.
If the customer.id and customer.name matches I treat the objects the equal.

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();
    }

}

I referred to generating hashcode.
I am little unsure about concatenating strings and using that as a hashcode.
Is this safe and sound what I am trying to do ?

最佳回答

请参阅哈希码问题,了解基于多个字段返回一个哈希码的相当简单的方法。

说到这里,我不会自己从EqualityComparer<T>派生 - 我会直接实现IEqualityComparer<T>。我不确定EqualityComparer<T>在这里真正给你带来了什么价值,除了实现非泛型的IEqualityComparer外。

还有两件事情:

  • You should handle nullity in 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;
}
问题回答

您应该从可能发生“冲突”的角度看待它,例如当两个不同的对象获得相同的哈希码时。这可能发生在“1,2any”和“12, any”这样的配对中,这些配对的值为“id”和“name”。如果您的数据不可能出现这种情况,那么就可以继续进行。否则,您可以将其更改为类似于:

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

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为我生成相等性和哈希码实现。我已经多次测试过他们的实现,发现它比我手写的任何东西都要好。所以我通常会采用我不需要输入的实现。





相关问题
热门标签