C#隐式转换和==运算符

Arn*_*psa 7 c# operators type-conversion equals-operator

上下文的一些代码:

class a
{

}

class b
{
    public a a{get;set;}
    public static implicit operator a(b b)
    {
        return b.a;
    }
}

  a a=null;
  b b=null;
  a = b;

  //compiler: cannot apply operator '==' to operands of type tralala...
  bool c = a == b; 
Run Code Online (Sandbox Code Playgroud)

是否可以在不同类型的实例上使用==运算符,其中一个可以隐式转换为另一个?我错过了什么?

编辑:
如果类型必须是相同的调用==,那么为什么

int a=1;
double b=1;
bool c=a==b; 
Run Code Online (Sandbox Code Playgroud)

作品?

Nol*_*rin 15

implicit操作仅适用于分配.

您想要重载equality(==)运算符,如下所示:

class a
{
    public static bool operator ==(a x, b y)
    {
        return x == y.a;
    }

    public static bool operator !=(a x, b y)
    {
        return !(x == y);
    }
}

class b
{
    public a a{get;set;}
    public static implicit operator a(b b)
    {
        return b.a;
    }
}
Run Code Online (Sandbox Code Playgroud)

这应该允许您比较两个类型的对象ab您的帖子中建议.

var x = new a();
var y = new b();
bool c = (x == y); // compiles
Run Code Online (Sandbox Code Playgroud)

注意:

我推荐简单地覆盖GetHashCodeEquals方法,正如编译器警告的那样,但是你似乎想要压制它们,你可以按如下方式做到这一点.

将您的班级声明更改a为:

#pragma warning disable 0660, 0661
class a
#pragma warning restore 0660, 0661
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)


Eri*_*ert 11

是否可以在不同类型的实例上使用==运算符,其中一个可以隐式转换为另一个?

是.

我错过了什么?

这是规范的相关部分.你错过了突出显示的单词.

预定义的引用类型相等运算符要求两个操作数都是引用类型值或文字空值.此外, 从操作数的类型到另一个操作数的类型存在标准的隐式转换.

根据定义,用户定义的转换不是标准转换.这些是参考类型.因此,预定义的引用类型相等运算符不是候选者.

如果类型必须是相同的调用==,那么为什么[double == int]有效?

您认为类型必须相同的假设是不正确的.有一个从int到double的标准隐式转换,并且有一个相等运算符,它需要两个双精度数,所以这是有效的.

我想你也错过了这一点:

使用预定义的引用类型相等运算符来比较两个在编译时已知不同的引用是一个编译时错误.例如,如果操作数的编译时类型是两个类类型A和B,并且如果A和B都不是从另一个派生,那么两个操作数就不可能引用同一个对象.因此,该操作被认为是编译时错误.