让我说我上课了:
public class Ident
{
public String Name { get; set; }
public String SName { get; set; }
}
还有一个:
class IdenNode
{
public Ident id { get; set; }
public List<IdenNode> Nodes { get; set; }
public IdenNode()
{
Nodes = new List<IdenNode>();
}
}
我想谨慎使用HashSet<IdenNode>
,当它的id.Names为Equal时,它的两个元素是相同的(Equal)。
所以,我要覆盖Equals
和GetHashCode
,如下:
public override bool Equals(object obj)
{
IdenNode otherNode = obj as IdenNode;
return otherNode != null &&
otherNode.id != null &&
id.Name == otherNode.id.Name;
}
public override int GetHashCode()
{
if (id != null)
return id.Name.GetHashCode();
else
// what should I write here?
}
我认为对吗?如果是这样,我应该在GetHashCode
中放置什么?
更新
请告诉我是否可以在==
方法中使用!=
和Equals
?或者可能是ReferenceEquals
或其他?
另外,我应该覆盖运算符==
和!=
吗?
答案 0 :(得分:7)
如果id
(或id.Name
)为null,则返回0完全正常。Nullable<T>
(如int?
)为“null”值返回0。
请记住,从GetHashCode()
返回相同值的两个对象并不意味着相等 - 它只意味着两个对象可能相等。然而,翻转是两个“相等”对象必须返回相同的哈希码。这两个原则似乎都是通过您对Equals
和GetHashCode
答案 1 :(得分:4)
小心 nulls !你有很多这些。照顾 StackOverflow :在Equals
方法中尝试不使用 ==和!=。通常,我们会在 null 的情况下将 0 作为哈希码返回,例如:
public override bool Equals(object obj) {
// Often we should compare an instance with itself,
// so let's have a special case for it (optimization)
if (Object.ReferenceEquals(obj, this))
return true;
IdenNode other = obj as IdenNode;
// otherNode != null line in your code can cause StackOverflow:
// "!=" calls "Equals" which in turn calls "!=" etc...
if (Object.ReferenceEquals(null, other))
return false;
// Id can be null
if (Object.ReferenceEquals(id, other.id))
return true;
else if (Object.ReferenceEquals(id, null) || Object.ReferenceEquals(other.id, null))
return false;
// Let's be exact when comparing strings:
// i.e. should we use current locale or not etc
return String.Equals(id.Name, other.id.Name, StringComparison.Ordinal);
}
public override int GetHashCode() {
// It's typical to return 0 in case of null
if (Object.ReferenceEquals(null, id))
return 0;
else if (Object.ReferenceEquals(null, id.Name)) // <- Name can be null as well!
return 0;
return id.Name.GetHashCode();
}
答案 2 :(得分:2)
如果是这样,我应该在GetHashCode中放置什么?
归零是好的。请注意,在名称上定义值相等是一个坏主意;我知道美国至少有三个Eric Lippert
,而且他们不是我。有数百万,可能是数十亿的名字发生碰撞的人。
请告诉我在Equals方法中使用“==”和“!=”是否可以?或者可能是ReferenceEquals或其他一些?
我的建议是:在混合引用和值相等时,非常清楚。如果你打算引用相等,请说明。
另外,我应该覆盖运算符“==”和“!=”?
是。让Equals
表示一件事而==
表示另一件事令人困惑。