为什么C#编译器不调用隐式转换操作符? [英] Why C# compiler doesn't call implicit cast operator?

查看:102
本文介绍了为什么C#编译器不调用隐式转换操作符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有以下类型:

struct MyNullable<T> where T : struct
{
    T Value;

    public bool HasValue;

    public MyNullable(T value)
    {
        this.Value = value;
        this.HasValue = true;
    }

    public static implicit operator T(MyNullable<T> value)
    {
        return value.HasValue ? value.Value : default(T);
    }
}

和尝试编译下面的代码片段:

And try to compile following code snippet:

MyNullable<int> i1 = new MyNullable<int>(1);
MyNullable<int> i2 = new MyNullable<int>(2);

int i = i1 + i2;

这剪断编译良好,没有出现错误。 。I1和I2强制转换为整数,并增加评估

This snipped compiled well and without errors. i1 and i2 casts to integer and addition evaluated.

但是,如果我们有以下类型:

But if we have following type:

struct Money
{
    double Amount;
    CurrencyCodes Currency; /*enum CurrencyCode { ... } */

    public Money(double amount, CurrencyCodes currency)
    {
        Amount = amount;
        Currency = currency;
    }

    public static Money operator + (Money x, Money y)
    {
        if (x.Currency != y.Currency)
            // Suppose we implemented method ConvertTo
            y = y.ConvertTo(x.Currency); 

        return new Money(x.Amount + y.Amount, x.Currency);
    }
}



尝试编译另一个代码片段:

Try to compile another code snippet:

MyNullable<Money> m1 = 
   new MyNullable<Money>(new Money(10, CurrenciesCode.USD));
MyNullable<Money> m2 = 
   new MyNullable<Money>(new Money(20, CurrenciesCode.USD));

Money m3 = m1 + m2;

和现在的问题,为什么编译器生成的错误CS0019:运算符+不能应用到类型的操作数'MyNullable<钱>'和'MyNullable<钱> 的?

And now the question, why compiler generate "error CS0019: Operator '+' cannot be applied to operands of type 'MyNullable<Money>' and 'MyNullable<Money>'"?

推荐答案

马克在右边线 - 这是在C#3.0规范第7.2.4节 - 二元运算符重载分辨率

Marc is on the right lines - it's section 7.2.4 in the C# 3.0 spec - Binary Operator Overload Resolution.

基本上,步骤如下:


  • 我们需要解决的执行情况X + Y,其中X和Y均为 MyNullable<钱>

  • 纵观第7.2.5节(候选的用户定义运算),我们结束了一个空集,如 MyNullable< T> 不超载+。

  • 早在7.2.4的候选运算符集是内置组二进制运营商+,即INT + INT,十进制小数+等

  • 在7.4.3重载决策规则的然后应用的。当我们正在做的 MyNullable<&诠释GT; + MyNullable< INT> 这个作品,因为每一个参数来 INT 的隐式转换的 - 但是当我们正在做 MyNullable<金钱与GT; + MyNullable<钱> 它的的工作,因为理财+金钱不在候选运算符集

  • We need to resolve the implementation for "X + Y" where X and Y are both MyNullable<Money>.
  • Looking at section 7.2.5 (candidate user-defined operators) we end up with an empty set, as MyNullable<T> doesn't overload +.
  • Back in 7.2.4 the set of candidate operators is the built-in set of binary operators for +, i.e. int+int, decimal+decimal etc.
  • Overload resolution rules in 7.4.3 are then applied. When we're doing MyNullable<int> + MyNullable<int> this works because of the implicit conversions of each argument to int - but when we're doing MyNullable<Money> + MyNullable<Money> it doesn't work because Money + Money isn't in the set of candidate operators.

这篇关于为什么C#编译器不调用隐式转换操作符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆