最稳健的Equals实现自定义类在C#中值相等
题
说我有一个POINT2类,并且我想要实现以下等于:
public override bool Equals ( object obj )
public bool Equals ( Point2 obj )
这是从有效C#3书:
public override bool Equals ( object obj )
{
// STEP 1: Check for null
if ( obj == null )
{
return false;
}
// STEP 3: equivalent data types
if ( this.GetType ( ) != obj.GetType ( ) )
{
return false;
}
return Equals ( ( Point2 ) obj );
}
public bool Equals ( Point2 obj )
{
// STEP 1: Check for null if nullable (e.g., a reference type)
if ( obj == null )
{
return false;
}
// STEP 2: Check for ReferenceEquals if this is a reference type
if ( ReferenceEquals ( this, obj ) )
{
return true;
}
// STEP 4: Possibly check for equivalent hash codes
if ( this.GetHashCode ( ) != obj.GetHashCode ( ) )
{
return false;
}
// STEP 5: Check base.Equals if base overrides Equals()
System.Diagnostics.Debug.Assert (
base.GetType ( ) != typeof ( object ) );
if ( !base.Equals ( obj ) )
{
return false;
}
// STEP 6: Compare identifying fields for equality.
return ( ( this.X.Equals ( obj.X ) ) && ( this.Y.Equals ( obj.Y ) ) );
}
是矫枉过正?
解决方案
与继承层次支持平等是棘手的。你需要找出你的意思是什么。你真的需要继承吗?如果没有 - 如果POINT2直接从System.Object派生,而你可以把它密封,生活变得更容易一点。在这种情况下我会使用:
public override bool Equals (object obj)
{
return Equals(obj as Point2);
}
public bool Equals (Point2 obj)
{
// STEP 1: Check for null if nullable (e.g., a reference type)
// Note use of ReferenceEquals in case you overload ==.
if (object.ReferenceEquals(obj, null))
{
return false;
}
// STEP 2: Check for ReferenceEquals if this is a reference type
// Skip this or not? With only two fields to check, it's probably
// not worth it. If the later checks are costly, it could be.
if (object.ReferenceEquals( this, obj))
{
return true;
}
// STEP 4: Possibly check for equivalent hash codes
// Skipped in this case: would be *less* efficient
// STEP 5: Check base.Equals if base overrides Equals()
// Skipped in this case
// STEP 6: Compare identifying fields for equality.
// In this case I'm using == instead of Equals for brevity
// - assuming X and Y are of a type which overloads ==.
return this.X == obj.X && this.Y == obj.Y;
}
其他提示
不是真的 - 你占几乎每一种可能性。如果这个代码是不是一个从无到有的应用程序的任何其他你应该考虑这种做法的好处,因为由于怪异的对象平等的行为逻辑错误是痛苦的调试。
在我看来像你想要什么。这整个块归结为:
“如果是完全一样的情况下,返回true。如果他们有相同的X和Y值单独的实例,返回true。所有其他情况下(NULL,不同类型,不同的x / y值)返回false。”
它比的我的想写的equals方法当然更多的代码。有很多多余的检查,如检查的ReferenceEquals和哈希码的(我知道这些检查是多余的,因为在结构相等的功能检查的最后几行)。专注于代码这是简单和可读性。
public bool Equals(object o)
{
Point2 p = o as Point2;
if (o != null)
return this.X == o.X && this.Y == o.Y;
else
return false;
}
由于您的equals方法使用结构平等,确保你重写GetHashCode根据您的领域以及实现。
不隶属于 StackOverflow