C# 运算符函数+;具有两个隐式类型转换';行不通

C# 运算符函数+;具有两个隐式类型转换';行不通,c#,casting,operator-overloading,implicit-conversion,ginac,C#,Casting,Operator Overloading,Implicit Conversion,Ginac,我正在尝试将一些部件从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"

我正在尝试将一些部件从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 {
}
正确的顺序应该是:隐式转换符号->基本->ex,然后是数字->基本->ex,然后使用ex运算符+(ex,ex)函数

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

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


+运算符实际上从第一个操作数确定其类型,在您的示例中,第一个操作数是符号。当第一个操作数是ex时,ex+ex将尝试隐式转换第二个操作数。

问题在于
运算符+
根据MSDN,如果
operator+
方法中的任何参数都不是编写该方法的类类型,编译器将抛出错误

此代码将起作用,因为您正在将至少一个参数转换为
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
    }
}

我不认为第一个参数和第二个参数之间存在不对称,也不完全准确。
+
运算符(和所有二进制运算符)确定将基于左操作数或右操作数对其执行运算符重载的类。但是,否则您是正确的——它不会从赋值左侧的推断类型中获取。
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
    }
}