【发布时间】:2014-09-30 18:00:33
【问题描述】:
我正在创建一个包含多个属性的自定义类的集合。下面是课程。
public class OnlineProductHierarchy
{
public DateTime InsertDate { get; set; }
public string InsertUserId { get; set; }
public DateTime AmendDate { get; set; }
public string AmendUserId { get; set; }
public string Product { get; set; }
public string TextField { get; set; }
public string Value { get; set; }
public bool IsDefault { get; set; }
}
为了让我的班级的两个对象被认为是相等的,TextField、Value 和 Product 必须相同,或者 TextField 和 Value 属性必须相同,如果 IsDefault 是真的
所以我有两种不同的方法来衡量平等,如果其中一种是真的,那么对象应该被认为是平等的。我这样做是为了在创建集合时使用 HashSet 来删除重复项。
使用普通列表并通过 LINQ 比较属性不是一种选择,因为我需要良好的性能。
到目前为止,我有此代码检查我的第一个条件之间的相等性,但我不确定如何修改它以包含我的第二个质量条件
public override bool Equals(object obj)
{
OnlineProductHierarchy o = obj as OnlineProductHierarchy;
return o != null && o.Product.ToUpper()
== this.Product.ToUpper() && o.Value.ToUpper() == this.Value.ToUpper()
&& o.TextField.ToUpper() == this.TextField.ToUpper();
}
public override int GetHashCode()
{
return this.Product.ToUpper().GetHashCode() ^
this.TextField.ToUpper().GetHashCode()
^ this.Value.ToUpper().GetHashCode();
}
当添加到 TextField、Value 和 Product 规则的 hastset 时,此代码现在可以正确识别重复项,但我如何添加到此以包含我的第二条规则?
编辑
在 cmets 的帮助和回答下,似乎无法在单个 Equals + GetHashCode 方法中做我想做的事。
因此,@Lee 建议的我的替代解决方案是创建两个具有不同 IEqualityComparer 实现的 HastSet,如果在添加时其中任何一个失败,我可以识别重复记录。
【问题讨论】:
-
请记住,Equals 和 GetHashCode 应该遵循传递相等,即。如果
a == b和b == c,那么a == c。您不能保证这一点,因此您将遇到大问题。我会建议找到一种不同的方式来做到这一点。 -
如果没有“自然”平等措施,则创建
IEqualityComparer<OnlineProductHierarchy>的实现并将它们传递给任何集合。 -
@Lee 有没有办法将两个不同的 IEqualityComparer 传递给同一个集合?在 HashSet 的构造函数中,我只看到一个选项。那么我是否正确地假设我必须创建两个不同的集合并比较结果?