实现IEqualityComparer的模型对象与为实现IEqualityComparer的模型创建新类之间的区别

时间:2016-03-31 13:32:57

标签: c# linq

关于何时应该执行以下任一操作,我感到有点困惑:

public class Product : IEquatable<Comparer> 
{
}

VS

public class ProductComparer : IEqualityComparer<Comparer> 
{
}

例如:如果我使用技术#2并想要做一个linq语句,它将合并两个类型为Product的列表,但是为了避免重复,我可以很容易地做到这一点:

mergedProducts = products.Union(extraProducts, new ProductComparer()).ToList();

但是,如果我决定采用技巧#1,我仍然可以使用linq或var equal = ProductA == ProductB之类的东西做同样的事情吗?

1 个答案:

答案 0 :(得分:2)

当您的类型具有单个默认的相等比较时,您希望实现IEquatable<T>。如果要为给定类型实现多个自定义相等比较,可以让多个类实现IEqualityComparer<T>并将它们传递给各种LINQ方法。

例如,您可以拥有一个实现IEquatable<Person>的人员类:

public class Person : IEquatable<Person>
{
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }

    public string Name { get; }
    public int Age { get; }

    public bool Equals(Person other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return string.Equals(Name, other.Name) && Age == other.Age;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((Person) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return ((Name?.GetHashCode() ?? 0)*397) ^ Age;
        }
    }

    public static bool operator ==(Person left, Person right)
    {
        return Equals(left, right);
    }

    public static bool operator !=(Person left, Person right)
    {
        return !Equals(left, right);
    }
}

但是现在你想要实现一个自定义比较器,它只根据人名进行相等性检查。您可以实施自定义IEqualityComparer<Person>

public class ByNamePersonComparer : IEqualityComparer<Person>
{
    public bool Equals(Person x, Person y)
    {
        return x.Name.Equals(y.Name, StringComparison.OrdinalIgnoreCase);
    }

    public int GetHashCode(Person obj)
    {
        return obj.GetHashCode();
    }
}