实现相等运算符的抽象类

假设我定义了以下抽象类:


public abstract class ValueEquality<T> : IEquatable<T> 

    where T : ValueEquality<T>

{

    public override bool Equals(object obj)

    {

        return Equals(obj as T);

    }


    public static bool operator ==(ValueEquality<T> lhs, object rhs)

    {

        if (ReferenceEquals(lhs, rhs))

        { 

            return true;

        }

        else if (ReferenceEquals(lhs, null) || ReferenceEquals(rhs, null))

        {

            return false;

        }

        else

        {

            return lhs.Equals(rhs);

        }

    }


    public static bool operator !=(ValueEquality<T> lhs, object rhs)

    {

        return !(lhs == rhs);

    }


    public bool Equals(T other)

    {

        return other != null && EqualNoNull(other);

    }


    public abstract override int GetHashCode();


    public abstract bool EqualNoNull(T other);

}

然后创建一个类C,如下所示:


public class C : MyEquatable<C>

{

    public override bool EqualsNoNull(C other)

    {

        ...

    }


    public override int GetHashCode()

    {

        ...

    }

}

如果我有代码:


C x1;

C x2;

bool equal = x1 == x2;

这最终会调用 equals 方法C吗?这种方法有什么问题吗?


编辑:修复了答案引发的代码中的一些问题。


守着一只汪
浏览 100回答 2
2回答

繁花如伊

此代码将执行无限循环:public override bool Equals(object obj){&nbsp; &nbsp; try&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; T otherT = (T) obj;&nbsp; &nbsp; &nbsp; &nbsp; return Equals(this, otherT);&nbsp; &nbsp; }&nbsp; &nbsp; catch (InvalidCastException)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; }}它会Equals(object obj)一次又一次地调用。正确的实现:public abstract class MyEquatable<T> : IEquatable<T>&nbsp; &nbsp; where T : MyEquatable<T>{&nbsp; &nbsp; public override bool Equals(object obj)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (ReferenceEquals(null, obj))&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if (ReferenceEquals(this, obj))&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if (obj.GetType() != this.GetType())&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return this.Equals((MyEquatable<T>)obj);&nbsp; &nbsp; }&nbsp; &nbsp; protected bool Equals(MyEquatable<T> other)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return this.Equals(other as T);&nbsp; &nbsp; }&nbsp; &nbsp; public static bool operator ==(MyEquatable<T> lhs, object rhs)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return Equals(lhs, rhs);&nbsp; &nbsp; }&nbsp; &nbsp; public static bool operator !=(MyEquatable<T> lhs, object rhs)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return Equals(lhs, rhs);&nbsp; &nbsp; }&nbsp; &nbsp; public abstract bool Equals(T other);&nbsp; &nbsp; public abstract override int GetHashCode();}x1 == x2将调用运算符==of MyEquatable,那将调用Equals(object obj)。最后,它在类中调用Equals(T other)覆盖C

慕容3067478

遵循文档中通常建议的另一种实现public abstract class MyEquatable<T> : IEquatable<T>&nbsp; &nbsp; where T : MyEquatable<T> {&nbsp; &nbsp; public override bool Equals(object obj) {&nbsp; &nbsp; &nbsp; &nbsp; if (ReferenceEquals(obj, null) || obj.GetType() != GetType())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; var valueObject = obj as T; //Note the cast&nbsp; &nbsp; &nbsp; &nbsp; if (ReferenceEquals(valueObject, null))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; return Equals(valueObject); //Calls Equals(T other)&nbsp; &nbsp; }&nbsp; &nbsp; public abstract bool Equals(T other);&nbsp; &nbsp; public abstract override int GetHashCode();&nbsp; &nbsp; public static bool operator ==(MyEquatable<T> left, MyEquatable<T> right) {&nbsp; &nbsp; &nbsp; &nbsp; if (ReferenceEquals(left, null) && ReferenceEquals(right, null))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; &nbsp; &nbsp; if (ReferenceEquals(left, null) || ReferenceEquals(right, null))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; return left.Equals(right);&nbsp; &nbsp; }&nbsp; &nbsp; public static bool operator !=(MyEquatable<T> left, MyEquatable<T> right) {&nbsp; &nbsp; &nbsp; &nbsp; return !(left == right);&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP