views:

43

answers:

2

hi, I'm trying to port some parts from ginac (www.ginac.de) to C#. But I encountered this:

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

The correct order should be: implicitly cast symbol->basic->ex, then numeric->basic->ex and then use the ex operator+(ex,ex) function.

In which order is the lookup for implicit casting functions and operator functions done? Is there any way around this?

+1  A: 

Cast the first operand to "ex". The first operand of the + operator will not be implicitly cast. You need to use an explicit cast.

The + operator actually determines its type from the first operand, which is symbol in your case. When the first operand is an ex, then the ex+ex will attempt the implicit cast of the second operand.

Les
I don't think there is an asymmetry between first and second param
CodeInChaos
@Les, not entirely accurate. The `+` operator (and all binary operators) determines the class for which the operator overload will be taken based on *either* the left operand *or* the right operand. But otherwise you are correct -- it will *not* be taken from the inferred type on the left-hand-side of the assignment.
Kirk Woll
+2  A: 

The problem is with the operator + According to MSDN, the compiler throws error if none of the parameter in operator + method is of class type in which the method is written. 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.
}

This code will work because you are converting at least one of the parameters to ex type:

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