我正在尝试比较两个List<T>
中的自定义类型,并使用Intersect
/ Except
方法。平等由这种类型的三个字段决定。相等性不仅仅基于普通条件(所有字段都包含相同的数据)。我当然实施了IEqualityComparer<T>
。我的问题是,一旦hashCode不相同,GetHashCode()
方法返回不相等,这对我没有帮助,因为在我的情况下这不是真的。
当相等性基于多个条件时,有没有办法比较两个自定义对象,所以我可以使用intersect / except / distinct等...?
这是我的代码:
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()
}
答案 0 :(得分:2)
你的工作是提供这样的GetHashCode()
,它返回的值对于 不同的对象是不同的(在尽可能多的情况下;你仍然可以返回相同的哈希码对于不相等的对象),对于可能相等的对象总是相同的(在所有情况下;对于相等的对象,您可能不会返回不同的哈希码)。
例如,如果您比较的三个字段之一是int
,则可以将该字段作为GetHashCode()
返回。
但是,如果很难想出一些聪明的东西,你可以返回一个常量,例如42
。这种方式Equals()
将被调用所有对象,提供预期的结果,尽管性能最差。
答案 1 :(得分:0)
不确定您的基础类型中是否存在GetHashCode的其他问题,但这是自定义类型的示例,如果只有前两个字段相同,则返回true的IEqualityComparer。这将允许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()
代替==
来比较对象。