Оператор-функция + с двумя неявными приведениями не работает

Я пытаюсь перенести некоторые части с 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 operator+(ex,ex).

В каком порядке выполняется поиск функций неявного приведения и операторных функций? Есть ли способ обойти это?


person Fabian Fritz    schedule 23.10.2010    source источник


Ответы (2)


Приведите первый операнд к «ex». Первый операнд оператора + не будет неявно приведен. Вам нужно использовать явное приведение.

Оператор + фактически определяет его тип из первого операнда, который в вашем случае является символом. Если первым операндом является ex, то ex+ex попытается выполнить неявное приведение второго операнда.

person Les    schedule 23.10.2010
comment
Я не думаю, что есть асимметрия между первым и вторым параметром - person CodesInChaos; 23.10.2010
comment
не совсем точно. Оператор + (и все бинарные операторы) определяет класс, для которого будет принята перегрузка оператора, на основе либо левого операнда, или правого операнда. Но в остальном вы правы - он не будет взят из предполагаемого типа в левой части присваивания. - person Kirk Woll; 23.10.2010

Проблема с operator +. Согласно MSDN, компилятор выдает ошибку, если ни один из параметров в методе operator + не относится к типу класса, в котором написан метод. Ссылка на документацию.

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
    }
}
person Nayan    schedule 23.10.2010