我有以下课程:
public class OrderRule {
public OrderDirection Direction { get; set; }
public String Property { get; set; }
}
它的HashSet:
HashSet<OrderRule> rules = // ...
如果属性相等,我需要将OrderRules视为相等。
我该怎么做?
答案 0 :(得分:4)
由于此等式的规范不是来自OrderRule类,而是来自您的集合,因此请使用接受IEqualityComparer的HashSet的构造函数重载。
public class MyOrderRuleComparer : EqualityComparer<OrderRule>
{
private IEqualityComparer<string> _c = EqualityComparer<string>.Default;
public override bool Equals(OrderRule l, OrderRule r)
{
return _c.Equals(l.Property, r.Property);
}
public override int GetHashCode(OrderRule rule)
{
return _c.GetHashCode(rule.Property);
}
}
...
HashSet<OrderRule> rules = new HashSet(new MyOrderRuleComparer());
请注意,通过使用OrderRule.Property作为键,您意味着在将实例添加到集合后它不能更改。这就是为什么实施IEquatable<OrderRule>
可能是最好的方法,具体取决于您的开发团队。
答案 1 :(得分:3)
如果我添加两个具有相同属性但方向不同的OrderRules 仍然需要两者被认为是平等的
您可以覆盖Equals
和GethashCode
和/或实施IEquatable<OrderRule>
:
public class OrderRule: IEquatable<OrderRule>
{
public OrderRule(string property)
{
this.Property = property;
}
public OrderDirection Direction { get; set; }
public String Property { get; }
public OrderRule Rule { get; set; }
public bool Equals(OrderRule other)
{
return (other != null && other.Property == this.Property);
}
public override int GetHashCode()
{
return Property?.GetHashCode() ?? int.MinValue;
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
if(ReferenceEquals(this, obj))
return true;
OrderRule other = obj as OrderRule;
return this.Equals(other);
}
}
请注意,我已将该属性设置为只读,因为您无法修改GetHashCode
中使用的属性或字段。
Why?:“指南:GetHashCode返回的整数永远不会改变 理想情况下,可变对象的哈希码应仅从不能变异的字段计算,因此对象的哈希值在其整个生命周期内都是相同的。“
此值为f.e.在字典或HashSet中用于计算哈希码。如果在添加对象后它会发生变化,则无法再找到它。