为了账号安全,请及时绑定邮箱和手机立即绑定

实现相等运算符的抽象类

实现相等运算符的抽象类

C#
守着一只汪 2022-06-12 14:38:43
假设我定义了以下抽象类: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吗?这种方法有什么问题吗?编辑:修复了答案引发的代码中的一些问题。
查看完整描述

2 回答

?
繁花如伊

TA贡献2012条经验 获得超12个赞

此代码将执行无限循环:


public override bool Equals(object obj)

{

    try

    {

        T otherT = (T) obj;

        return Equals(this, otherT);

    }

    catch (InvalidCastException)

    {

        return false;

    }

}

它会Equals(object obj)一次又一次地调用。正确的实现:


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

    where T : MyEquatable<T>

{

    public override bool Equals(object obj)

    {

        if (ReferenceEquals(null, obj))

        {

            return false;

        }


        if (ReferenceEquals(this, obj))

        {

            return true;

        }


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

        {

            return false;

        }


        return this.Equals((MyEquatable<T>)obj);

    }


    protected bool Equals(MyEquatable<T> other)

    {

        return this.Equals(other as T);

    }



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

    {

        return Equals(lhs, rhs);

    }


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

    {

        return Equals(lhs, rhs);

    }


    public abstract bool Equals(T other);

    public abstract override int GetHashCode();

}

x1 == x2将调用运算符==of MyEquatable,那将调用Equals(object obj)。最后,它在类中调用Equals(T other)覆盖C


查看完整回答
反对 回复 2022-06-12
?
慕容3067478

TA贡献1773条经验 获得超3个赞

遵循文档中通常建议的另一种实现


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

    where T : MyEquatable<T> {


    public override bool Equals(object obj) {


        if (ReferenceEquals(obj, null) || obj.GetType() != GetType())

            return false;


        var valueObject = obj as T; //Note the cast


        if (ReferenceEquals(valueObject, null))

            return false;


        return Equals(valueObject); //Calls Equals(T other)

    }


    public abstract bool Equals(T other);

    public abstract override int GetHashCode();


    public static bool operator ==(MyEquatable<T> left, MyEquatable<T> right) {

        if (ReferenceEquals(left, null) && ReferenceEquals(right, null))

            return true;


        if (ReferenceEquals(left, null) || ReferenceEquals(right, null))

            return false;


        return left.Equals(right);

    }


    public static bool operator !=(MyEquatable<T> left, MyEquatable<T> right) {

        return !(left == right);

    }

}


查看完整回答
反对 回复 2022-06-12
  • 2 回答
  • 0 关注
  • 99 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号