对于像Point3这样的引用类型(类)(例如),这是一种过度杀伤,缺乏:
#region System.Object Members
public override bool Equals ( object obj )
{
//return this == ( Point3 ) obj;
if ( obj == null )
{
return false;
}
if ( this.GetType ( ) != obj.GetType ( ) )
{
return false;
}
return this.Equals ( ( Point3 ) obj );
}
public override int GetHashCode ( )
{
return this.X.GetHashCode ( ) ^ this.Y.GetHashCode ( ) ^ this.Z.GetHashCode ( );
}
public override string ToString ( )
{
return String.Format ( "[{0}, {1}, {2}]", this.X, this.Y, this.Z );
}
#endregion
#region IEquatable<Point3> Members
public bool Equals ( Point3 other )
{
if ( other == null )
{
return false;
}
if ( ReferenceEquals ( this, other ) )
{
return true;
}
if ( this.GetHashCode ( ) != other.GetHashCode ( ) )
{
return false;
}
if ( !base.Equals ( other ) )
{
return false;
}
return this == other;
}
#endregion
public static bool operator == ( Point3 v0, Point3 v1 )
{
return ( v0.X.IsEqual ( v1.X ) ) && ( v0.Y.IsEqual ( v1.Y ) ) && ( v0.Z.IsEqual ( v1.Z ) );
}
public static bool operator != ( Point3 v0, Point3 v1 )
{
return !( v0 == v1 );
}
请为我的基本类型(值和参考)中的值和引用类型进行调整或发布一个新的值,而不必在每次重新实现时都考虑太多。
编辑:这是针对不可变类型的。
答案 0 :(得分:4)
首先,不要陷入使用XOR作为组合运算符生成哈希码的陷阱。
否则,您将遇到以下问题,其中HC(x)表示“对象/值x的哈希码”:
HC(a,b) = HC(b,a)
HC(a,a) = HC(b,b) = 0
相反,选择至少考虑值的顺序的内容,如下所示:
hashcode = 23 // prime number
for each sub-value of the object, do:
hashcode = hashcode * 31 // another prime number
hashcode = hashcode + the hashcode of the sub-value
这将尽可能地保留订购。
答案 1 :(得分:3)
this.GetType()!= obj.GetType()
那会很慢。请使用obj is Type
。
ReferenceEquals
对于值类型是没有意义的,我假设Point3是。
我也不会在等式过程中使用哈希码检查。
答案 2 :(得分:2)
如果你真的进入了性能并且你的值x,y和z没有改变(至少经常),当你进行大量的比较时,你可以预先计算你的哈希码。然后在你的平等比较中尽早使用它。
但在这种情况下最好的是:使用分析器找到真正的瓶颈。
答案 3 :(得分:2)
另外,如果你要创建自己的Equals方法,你应该考虑实现IEquatable。这为您提供了一个比较相同类型的好的相等方法,通常可以将Equals(object)方法减少为(对于引用类型):
public override Equals(object other)
{
Point3 otherP = other as Point3;
return otherP != null && Equals(otherP); // calls the Equals(Point3) method
}
除了更好一点之外,如果类型是结构,这会减少一个盒子操作 - 如果IEquatable实现是隐式的,代码将自动使用类型化的Equals(Point3)方法,而不是使用Equals(object)这涉及一个盒子操作(实际上可能是在该方法中的unbox)