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

发布于 2024-07-20 02:51:06 字数 488 浏览 15 评论 0原文

上下文的一些代码:

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; 

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

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

int a=1;
double b=1;
bool c=a==b; 

有效呢?

Some code for context:

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; 

Is it possible to use == operator on different type instances, where one can implicitly convert to another? What did i miss?

Edit:
If types must be the same calling ==, then why

int a=1;
double b=1;
bool c=a==b; 

works?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

转身泪倾城 2024-07-27 02:51:06

隐式运算符仅适用于赋值。

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

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;
    }
}

这应该允许您比较 ab 类型的两个对象正如你的帖子中所建议的。

var x = new a();
var y = new b();
bool c = (x == y); // compiles

注意:

我建议简单地覆盖 GetHashCodeEquals 方法,正如编译器警告的那样,但是当您似乎想要抑制它们时,您可以按如下方式进行操作。

a 的类声明更改为:

#pragma warning disable 0660, 0661
class a
#pragma warning restore 0660, 0661
{
    // ...
}

The implicit operator only works for assignment.

You want to overload the equality (==) operator, as such:

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;
    }
}

This should then allow you to compare two objects of type a and b as suggested in your post.

var x = new a();
var y = new b();
bool c = (x == y); // compiles

Note:

I recommmend simply overriding the GetHashCode and Equals method, as the compiler warns, but as you seem to want to supress them, you can do that as follows.

Change your class declaration of a to:

#pragma warning disable 0660, 0661
class a
#pragma warning restore 0660, 0661
{
    // ...
}
萤火眠眠 2024-07-27 02:51:06

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

是的。

我错过了什么?

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

预定义的引用类型相等
运算符要求两个操作数
是引用类型值或
字面意义为空。 此外,标准
隐式转换存在于
任一操作数的类型为
另一个操作数。

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

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

您认为类型必须相同的假设是不正确的。 有一个从 int 到 double 的标准隐式转换,并且有一个接受两个双精度数的相等运算符,因此这是有效的。

我想你也错过了这一点:

使用以下命令会产生编译时错误
预定义引用类型相等
比较两个引用的运算符
已知是不同的
编译时。 例如,如果
操作数的编译时类型是
两个类类型 A 和 B,并且如果
A 和 B 均不源自
其他的,那就不可能了
两个操作数引用相同
目的。 因此,操作是
被认为是编译时错误。

Is it possible to use == operator on
different type instances, where one
can implicitly convert to another?

Yes.

What did i miss?

Here's the relevant portion of the specification. You missed the highlighted word.

The predefined reference type equality
operators require [that] both operands
are reference-type values or the
literal null. Furthermore, a standard
implicit conversion exists from the
type of either operand to the type of
the other operand.

A user-defined conversion is by definition not a standard conversion. These are reference types. Therefore, the predefined reference type equality operator is not a candidate.

If types must be the same calling ==,
then why [double == int] works?

Your supposition that the types must be the same is incorrect. There is a standard implicit conversion from int to double and there is an equality operator that takes two doubles, so this works.

I think you also missed this bit:

It is a compile-time error to use the
predefined reference type equality
operators to compare two references
that are known to be different at
compile-time. For example, if the
compile-time types of the operands are
two class types A and B, and if
neither A nor B derives from the
other, then it would be impossible for
the two operands to reference the same
object. Thus, the operation is
considered a compile-time error.

水中月 2024-07-27 02:51:06

我想您需要实际覆盖您感兴趣的类型的 == 运算符。即使类型是隐式可转换的,编译/运行时是否仍然会抱怨,您必须进行试验。

public static bool operator ==(a a, b b)
    {
        //Need this check or we can't do obj == null in our Equals implementation
        if (((Object)a) == null)
        {
            return false;
        }
        else
        {
            return a.Equals(b);
        }
    }

或者,只需使用 ole6ka 建议的 Equals 实现,并确保该实现执行您需要的类型转换。

I would imagine that you need to actually override the == operator for the types you are interested in. Whether the compile/runtime will still complain even if the types are implicity convertable is something you'll have to experiment with.

public static bool operator ==(a a, b b)
    {
        //Need this check or we can't do obj == null in our Equals implementation
        if (((Object)a) == null)
        {
            return false;
        }
        else
        {
            return a.Equals(b);
        }
    }

Alternatively just use Equals implementations like ole6ka suggests and ensure that the implementation does the type casting you need.

黑凤梨 2024-07-27 02:51:06

http://msdn.microsoft.com/en-us/library/8edha89s。 ASPX

在每种情况下,必须有一个参数
与类或结构相同的类型
声明运算符 (...)

http://msdn.microsoft.com/en-us/library/8edha89s.aspx

In each case, one parameter must be
the same type as the class or struct
that declares the operator (...)

摘星┃星的人 2024-07-27 02:51:06

用这个

 bool c = a.Equals(b);

Use this

 bool c = a.Equals(b);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文