IEqualityComparer<T> 和自定义类型
-
10-12-2019 - |
题
我正在尝试比较两种自定义类型 List<T>
并使用 Intersect
/ Except
方法。相等性由该类型的三个字段确定。相等性不仅仅基于普通条件(所有字段包含相同的数据)。我当然实施了 IEqualityComparer<T>
. 。我的问题是 GetHashCode()
一旦 hashCode 不同,方法返回不等于,这对我没有帮助,因为在我的情况下这不是真的。
当相等基于多个条件时,有什么方法可以比较两个自定义对象,以便我可以使用相交/例外/不同等...?
这是我的代码:
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()
}
解决方案
你的工作就是提供这样的服务 GetHashCode()
对于以下对象,它返回的值会有所不同 是 不同(在尽可能多的情况下;对于不相等的对象,您仍然可以返回相同的哈希码),并且对于以下对象将始终相同 可能 平等(在所有情况下;您不能为相同的对象返回不同的哈希码)。
例如,如果您比较的三个字段之一是 int
, ,您可以将该字段返回为 GetHashCode()
.
但是,如果很难想出一些巧妙的方法,您可以返回一个常量,例如 42
. 。这边走 Equals()
将为所有对象对调用,尽管以性能最低的方式提供预期结果。
其他提示
不确定您的基础类型中的 GetHashCode 是否存在其他问题,但这是自定义类型和 IEqualityComparer 的示例,如果只有前两个字段相同,则返回 true。这将允许 Except
ETC。处理类型。
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()
代替 ==
来比较对象。
不隶属于 StackOverflow