C# 对于值和引用类型,最完整的实现分别为Equals

C# 对于值和引用类型,最完整的实现分别为Equals,c#,.net,equals,C#,.net,Equals,对于像Point3(例如)这样的引用类型(类),这是一种过度杀伤力吗 #region System.Object Members public override bool Equals ( object obj ) { //return this == ( Point3 ) obj; if ( obj == null ) { return false; } if ( this.G

对于像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 );
}
#区域系统。对象成员
公共覆盖布尔等于(对象对象对象)
{
//返回this==(Point3)obj;
if(obj==null)
{
返回false;
}
if(this.GetType()!=obj.GetType())
{
返回false;
}
返回此.Equals((点3)obj);
}
公共覆盖int GetHashCode()
{
返回this.X.GetHashCode()^this.Y.GetHashCode()^this.Z.GetHashCode();
}
公共重写字符串ToString()
{
返回String.Format(“[{0},{1},{2}]”,this.X,this.Y,this.Z);
}
#端区
#区域可容纳成员
公共布尔等于(第3点其他)
{
如果(其他==null)
{
返回false;
}
if(ReferenceEquals(this,other))
{
返回true;
}
if(this.GetHashCode()!=other.GetHashCode())
{
返回false;
}
如果(!base.Equals(其他))
{
返回false;
}
返回this==other;
}
#端区
公共静态布尔运算符==(点3 v0,点3 v1)
{
返回(v0.X.IsEqual(v1.X))&&(v0.Y.IsEqual(v1.Y))&&(v0.Z.IsEqual(v1.Z));
}
公共静态布尔运算符!=(点3 v0,点3 v1)
{
返回!(v0==v1);
}
请对值和引用类型进行调整或发布一个新的值和引用类型,我可以在我的基本类型(值和引用)中使用它们,而无需在每次再次实现时考虑太多

编辑:这是针对不可变类型的

this.GetType()!=obj.GetType()

那会很慢。使用
obj是类型

ReferenceEquals
对于valuetypes是没有意义的,我假设第3点是


我也不会为相等过程中的哈希代码检查而烦恼。

首先,不要落入使用XOR作为组合运算符生成哈希代码的陷阱

否则,您将遇到以下问题,其中HC(x)表示“对象/值x的哈希代码”:

取而代之的是,选择至少考虑到值顺序的东西,如以下:

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

这将尽可能保留顺序。

如果您真的对性能感兴趣,并且您的值x、y和z没有变化(至少经常如此),那么在进行大量比较时,您可以预先计算哈希代码。然后在你的平等比较中尽早使用它


但是在这种情况下最好的方法是:使用分析器来找到真正的瓶颈。

此外,如果您正在创建自己的Equals方法,您应该考虑实现IEquatable。这为您提供了一个很好的相等方法来比较相同的类型,通常您可以将Equals(object)方法简化为(对于引用类型):


除了更好一点之外,如果类型是一个结构,这将减少一个box操作——如果IEquatable实现是隐式的,代码将自动使用类型化的Equals(Point3)方法,而不是使用包含box操作的Equals(object)(可能是该方法内部的unbox)

Erm。。。这里的问题是什么?你为什么要让别人为你工作?我可以理解征求意见,但要求我们为你解决问题是让你的帖子关闭的一个很好的方式。是的,我实际上提到了这是一种参考类型。我不是要求人们为我做这项工作。我要的是最完整的Equals实现,你得问问Knuth。我所知道的是,它产生的值通常不太容易发生冲突。至少(同样,Knuth),你应该选择两个互质的数字,也就是说,没有共同的因子。不,你不能使用散列进行可靠的相等性检查。如果散列值不相等,你可以停下来比较类型或其他任何东西。。。在大多数情况下,你会得到负面的打击。。。然后hashcode是一种非常快速的机制
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
public override Equals(object other)
{
    Point3 otherP = other as Point3;
    return otherP != null && Equals(otherP); // calls the Equals(Point3) method
}