加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 如果“==运算符未定义”会发生什么?

发布时间:2020-12-16 01:35:00 所属栏目:百科 来源:网络整理
导读:如果“==运算符未定义”会发生什么? 例: class a{ int variable = 0;}class b{ void proc() { a ref1 = new a(); a ref2 = new a(); bool cmp1 = ref1 == ref2;//? bool cmp2 = ref1 == ref1;//? }} 使用结构时是否有所不同? 编组(System.Runtime.Remotin
如果“==运算符未定义”会发生什么?

例:

class a
{
    int variable = 0;
}
class b
{
    void proc()
    {
        a ref1 = new a();
        a ref2 = new a();
        bool cmp1 = ref1 == ref2;//?
        bool cmp2 = ref1 == ref1;//?
    }
}

使用结构时是否有所不同?

编组(System.Runtime.Remoting.*)对象(单例)怎么样?

解决方法

对于用户定义的值类型,您的代码将无法编译.

具体来说,编译失败会出现以下错误:“运算符’==’不能应用于’a’和’a’类型的操作数.”

“The == and != operators cannot operate on a struct unless the struct explicitly overloads them.”

你必须超载both of them.你很可能不想在你的方法中使用默认的Equals(),因为
“…对于结构体,Object.Equals(Object)的默认实现(它是System.ValueType中的重写版本)通过使用反射来比较类型中每个字段的值来执行值相等性检查.当执行者时覆盖stuct中的虚拟Equals方法,目的是提供一种更有效的方法来执行值相等性检查,并可选择将结果基于struct的一个或多个字段的属性.“

对于用户定义的引用类型(简化的情况,如在OP的示例中):

“The == and != operators can be used with classes even if the class does not overload them. However,the default behavior is to perform a reference equality check. In a class,if you overload the Equals method,you should overload the == and != operators,but it is not required.”

如果不重载运算符,则很可能只有参考相等性测试.

“简化案例”,因为operator overload resolution可能会选择另一个实现而不是default.

//Minimal example,for demonstration only.
//No Equals(),GetHaschode() overload,no IEquatable<T>,null checks,etc..
class Program
{
    static void Main()
    {

        MyMoreDerived a = new MyMoreDerived() { fbase = 1,fderived = 3 };
        MyMoreDerived b = new MyMoreDerived() { fbase = 2,fderived = 3 };

        //Even though MyMoreDerived does not overload the operators,this
        //will succeed - the definition in MyDerived will be used.
        if (a == b)
        {
            //Reached,because the operator in MyDerived is used.
            Console.WriteLine("MyDerived operator used: a == b");
        }

        a.fderived = 2;
        b.fbase = 1;
        //a => {1,2} 
        //b => {1,3}
        //Since 2 != 3,the operator in MyDerived would return false.
        //However only the operator in MyBase will be used.
        if ((MyBase)a == (MyBase)b)
        {
            //Reached,because the operator in MyBase is used.
            Console.WriteLine("MyBase operator used: a == b");
        }

        b.fderived = 2;
        //a => {1,2}
        //Now both operator definitions would compare equal,//however they are not used.
        if ((object)a != (object)b)
        {
            //Reached,because the default implementation is used
            //and the references are not equal.
            Console.WriteLine("Default operator used: a != b");
        }

    }

    class MyBase
    {
        public int fbase;

        public static bool operator ==(MyBase x,MyBase y)
        {
            return x.fbase == y.fbase;
        }

        public static bool operator !=(MyBase x,MyBase y)
        {
            return x.fbase != y.fbase;
        }

    }

    class MyDerived : MyBase
    {
        public int fderived;

        public static bool operator ==(MyDerived x,MyDerived y)
        {
            return x.fderived == y.fderived;
        }

        public static bool operator !=(MyDerived x,MyDerived y)
        {
            return x.fderived != y.fderived;
        }

    }

    class MyMoreDerived : MyDerived
    {
    }

}

单身人士在引用类型的上下文中最有意义,其目的是返回一个特定的实例.我无法想象一个合理的情况,即引用是相同的但是对象与自身“不相等”.

即使使用远程处理,最好将操作合同与数据合同分开.
前者通常由服务器端的MarshalByRefObjects实现 – 实现接口定义的操作 – 后者的数据/消息类由值封送,可能由客户端和服务器共享.如果重载数据类中的运算符,这可能不是一个大问题.但是,我相信这些不应该引用/调用远程对象.

即使你提供了一个重载运算符的自定义客户端代理,这也是一个非常糟糕的做法和调试噩梦,隐藏在==和!=运算符后面的远程调用.(如果我理解你的意图,我不确定.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读