我有两个类似的对象:
class Container {
public HashSet<Item> Items { get; }
}
class Item {
public Container Parent { get; set; }
public string Value1 { get; set; }
public int Value2 { get; set; }
}
每个Item
实例必须属于Container
实例,并且两者之间存在一对多关系,并且两端始终保持同步。
我现在面临着实施一种方法,该方法会比较Item
的两个实例,以查看其Value1
和Value2
值是否匹配。该方法将不考虑Parent
值,因为我比较的每对实例在此值上肯定不同,所以这样做会使我实现的方法无用,因为它会有与false
方法相同的结果(object.ReferenceEquals
)。
我的问题如下。我应该将此方法实现为对象的public override bool Equals( object obj )
方法(以及GetHashCode
)吗?或者它忽略了它的Parent
属性的事实使我无法这样做?为什么或者为什么不?我的另一个想法是将其实现为public bool EqualsIgnoreParent( Item other )
,它不会覆盖任何东西;然后我可以从自定义比较器中调用它。
答案 0 :(得分:1)
感谢mikez's comment和Eric Lippert的blog post,我发现我不应该覆盖Item
的{{1}}或Equals
方法,因为{{ 1}}的实例是可变的并添加到GetHashCode
。
根据建议here,我决定将两个平等概念分开。
Item
的{{1}}和HashSet
方法。我将这些方法保留在Item
中。这就是Equals
将使用的内容。GetHashCode
的公共单例类,它嵌套在object
中并实现HashSet
。这就是我在我的问题中描述的比较逻辑。答案 1 :(得分:0)
我猜你想要实现IEquatable。所以我建议你只用Euqals(Item other)重载Euqals(对象),同时通过调用Equals(Item other)来覆盖Equals(对象)。
当然,让GetHashCode返回-1总是强制通过Equals进行相等比较。这里有一个解释为什么需要覆盖GetHashCode方法 - Why is it important to override GetHashCode when Equals method is overridden?
答案 2 :(得分:0)
是的,您可以使用Equals和GetHashCode,实现此功能,只要Value1和Value2不会更改或您的哈希值与任何更改无关。 (否则使用您的HashCode的集合将不起作用)
此外,您可以将Item类减少为基本成员
class Item {
public string Value1 { get; set; }
public int Value2 { get; set; }
}
并在另一个字典中维护关系:(如果正确实现GetHashCode,这将是有效的)
Dictionary<Item, Container> ContainersOfItems;
答案 3 :(得分:0)
我建议拆分Item可能更有意义,所以它看起来像:
class Container<TContent> {
public HashSet<Item<TContent>> Items { get; }
}
class Item<TContent> {
public Container Parent;
public TContent Content;
}
如果您这样做,那么您可以定义一种类型来保存您的内容,该类型具有适合该类型的Equals
方法,并使用HashSet
初始化您的IEqualityComparer<Item<TConcent>>
每个Item<TContent>
的{{1}}字段。
答案 4 :(得分:-1)
不要这样做,除非你100%确定父成员永远不会有任何不同。可能有许多你没想到的用例,(如果你需要将2个容器中的项目放在一个字典中怎么办?)所以我建议坚持设计。如果按照定义,平等只由其他成员决定,那就去吧。否则,不是。
您以后总是可以编写特定于案例的相等逻辑。请注意,Dictionary
,List
,HashSet
和其他收集可让您定义自定义IEqualityComparer
。
还有另一种选择,但要非常小心。覆盖两种方法,但使GetHashCode
比Equals
更宽容,这意味着,使不等对象具有相同的哈希码,而不是相反。让GetHashCode
忽略父成员,但不忽略Equals
。它不会伤害任何东西,然后如果你想忽略词典中的父成员,写一个IEqualityComparer
,用GetHashCode
的方式比较它们。