IEqualityComparer<;T>;和自定义类型

本文关键字:自定义 类型 lt IEqualityComparer gt | 更新日期: 2023-09-27 18:27:25

我正在尝试比较两个List<T>中的自定义类型,并使用Intersect/Except方法。相等性由三个此类字段决定。相等的基础不仅仅是普通条件(所有字段都包含相同的数据)。我当然实现了IEqualityComparer<T>。我的问题是,一旦hashCode不相同,GetHashCode()方法就会返回不相等的值,这对我没有帮助,因为在我的情况下这不是真的。

当等式基于多个条件时,有没有什么方法可以比较两个自定义对象,这样我就可以使用intersect/except/edistinct等。。。?

这是我的代码:

public bool Equals(ComparableObject x, ComparableObject y)
{
    if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
        return false;
    if (Object.ReferenceEquals(x, y))
        return true;
    if (x.Var1.Equals(y.Var1) && x.Var3.Equals(y.Var3) && !x.Var2.Equals(y.Var2))
        return false;
    if (x.Var1.Equals(y.Var1) && !x.Var3.Equals(y.Var3) && !x.Var2.Equals(y.Var2))
        return true;

    if (!x.Var1.Equals(y.Var1) && x.Var3.Equals(y.Var3) && !x.Var2.Equals(y.Var2))
        return false;
    if (!x.Var1.Equals(y.Var1) && x.Var3.Equals(y.Var3) && x.Var2.Equals(y.Var2))
        return true;
    if (x.Var1.Equals(y.Var1) && !x.Var3.Equals(y.Var3) && x.Var2.Equals(y.Var2))
        return false;
    if (!x.Var1.Equals(y.Var1) && !x.Var3.Equals(y.Var3) && x.Var2.Equals(y.Var2))
        return false;
    if (!x.Var1.Equals(y.Var1) && !x.Var3.Equals(y.Var3) && !x.Var2.Equals(y.Var2))
        return false;

    return x.Var1.Equals(y.Var1) && x.Var1.Equals(y.Var1) && x.Var3.Equals(y.Var3);
}

public int GetHashCode(ComparableObject x)
{
    return obj.Var1.GetHashCode() ^ obj.Var2.GetHashCode()^ obj.Var3.GetHashCode()
}

IEqualityComparer<;T>;和自定义类型

您的工作是提供这样的GetHashCode(),即对于不同的对象,它返回的值将不同(在尽可能多的情况下;对于不相等的对象,您仍然可以返回相同的哈希代码),而对于可能相等的对象(在所有情况下;您可能不会为相等的对象返回不同的哈希码)。

例如,如果比较的三个字段中有一个是int,则可以将该字段返回为GetHashCode()

然而,如果很难想出一些巧妙的方法,可以返回一个常量,例如42。通过这种方式,将为所有对象对调用Equals(),从而提供预期的结果,尽管这是性能最低的方式。

不确定您的底层类型中的GetHashCode是否有其他问题,但这是一个自定义类型和IEqualityComparer的示例,如果只有前两个字段相同,则返回true。这将允许Except等处理该类型。

    public class CustomType
    {
        public int Val1 { get; set; }
        public int Val2 { get; set; }
        public int Val3 { get; set; }
    }
    class CustomTypeComparer : IEqualityComparer<CustomType>
    {
        public bool Equals(CustomType x, CustomType y)
        { return x.Val1 == y.Val1 && x.Val2 == y.Val2; }
        public int GetHashCode(CustomType obj)
        { return obj.Val1.GetHashCode() ^ obj.Val2.GetHashCode(); }
    }

如果属性不是int这样的简单类型,则可能需要使用Equals()而不是==来比较对象。