【问题标题】:Operator-function + with two implicit casts doesn't work带有两个隐式转换的运算符函数 + 不起作用
【发布时间】:2010-10-23 11:00:38
【问题描述】:

我正在尝试将一些部分从 ginac (www.ginac.de) 移植到 C#。但是我遇到了这个:

class Program {

static void Main(string[] args) {

        symbol s = new symbol();          
        numeric n = new numeric();

        ex e = s + n; // "Operator + doesn't work for symbol, numeric"
    }
}

class ex {
    //this should be already be sufficient:
    public static implicit operator ex(basic b) {
        return new ex();
    }
    //but those doesn't work as well:
    public static implicit operator ex(numeric b) {
        return new ex();
    }
    public static implicit operator ex(symbol b) {
        return new ex();
    }

    public static ex operator +(ex lh, ex rh) {
        return new ex();
    }
}
class basic {      
}
class symbol : basic {
}
class numeric : basic {
}

正确的顺序应该是:隐式转换symbol->basic->ex,然后numeric->basic->ex再使用ex operator+(ex,ex)函数。

隐式转换函数和运算符函数的查找按什么顺序完成? 有没有办法解决这个问题?

【问题讨论】:

    标签: c# casting operator-overloading implicit-conversion ginac


    【解决方案1】:

    问题在于operator + 根据 MSDN,如果 operator + 方法中的参数都不是编写该方法的类类型,则编译器会抛出错误。 Link to documentation.

    class iii { //this is extracted from the link above.. this is not complete code.
    public static int operator +(int aa, int bb) ...  // Error CS0563
    // Use the following line instead:
    public static int operator +(int aa, iii bb) ...  // Okay.
    }
    

    此代码将起作用,因为您正在将至少一个参数转换为ex 类型:

    class basic { }
    class symbol : basic { }
    class numeric : basic { }
    
    class ex {
        public static implicit operator ex(basic b) {
            return new ex();
        }
    
        public static implicit operator basic(ex e) {
            return new basic();
        }
    
        public static ex operator + (basic lh, ex rh) {
            return new ex();
        }
    }
    
    class Program {
        static void Main(string[] args) {
            symbol s = new symbol();
            numeric n = new numeric();
    
            // ex e0 = s + n; //error!
            ex e1 = (ex)s + n; //works
            ex e2 = s + (ex)n; //works
            ex e3 = (ex)s + (ex)n; //works
        }
    }
    

    【讨论】:

      【解决方案2】:

      将第一个操作数转换为“ex”。 + 运算符的第一个操作数不会被隐式转换。您需要使用显式强制转换。

      + 运算符实际上从第一个操作数(在您的情况下为符号)确定其类型。当第一个操作数是 ex 时,ex+ex 将尝试对第二个操作数进行隐式转换。

      【讨论】:

      • 我认为第一个和第二个参数之间没有不对称
      • 不完全准确。 + 运算符(以及所有二元运算符)根据 任一 左操作数 右操作数确定将为其采用运算符重载的类。但否则你是正确的——它将不会取自赋值左侧的推断类型。
      猜你喜欢
      • 1970-01-01
      • 2019-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多