C# und ternärer Operator

Gast #1449485
Lesenswert?

Warum funktioniert in C# ...

MyBaseClass foo(bool bar)
{
    if (bar) return new MyDerivedClass1();
    else return new MyDerivedClass2();
}

... aber nicht ...

MyBaseClass foo(bool bar)
{
    return bar ? new MyDerivedClass1() : new MyDerivedClass2();
}

... ???

Fehlermeldung:

Type of conditional expression cannot be determined because there is no 
implicit conversion between 'MyDerivedClass1' and 'MyDerivedClass2'

Gruß,
Alex
#1449527
Lesenswert?

Im ersten Fall muß nur bei jedem return zur Basisklasse gecastet werden,
das geht immer.

Im zweiten Fall dagegen weiß der Compiler noch nicht (bzw. weigert
sich, es zu sehen), daß letztlich etwas in der Basisklasse rauskommen
soll, während er über den Auswahloperator nachdenkt. Für den aber
müssen die beiden Operanden zueinander kompatibel sein, zwei
verschiedene Ableitungen einer Basisklasse sind das von sich aus
nicht. Erst das Ergebnis von ?: würde in die Basisklasse gecastet
werden wegen des return, aber da ist es schon zu spät.
Gast #1449558
Lesenswert?

C# ist typstreng. Der Operator ?: hat genau einen Ergebnistyp. Welchen 
soll er denn in Deinem Fall nehmen? MyDerivedclass1, MyDerivedclass2 
oder MyBaseClass?

Wie Klugscheißer bereits geschrieben hat, kannst Du das Problem mit 
einem expliziten Type-Cast lösen. Oder aber Du machst, was der Compiler 
bemängelt: Implementiere doch einfach die impliziten Casts!
1
class MyDerivedClass1 {
2
    ...
3
    public static implicit operator MyBaseClass( MyDerivedClass1 val ) {
4
        return val; // ggf. (MyBaseClass)val
5
    }
6
    ...
7
}
8

9
class MyDerivedClass2 {
10
    ...
11
    public static implicit operator MyBaseClass( MyDerivedClass2 val ) {
12
        return val; // ggf. (MyBaseClass)val
13
    }
14
    ...
15
}
16

17
class MyBaseClass {
18
    ...
19
    public MyBaseClass Foo( MyDerivedClass1 o1, MyDerivedclass o2 ) {
20
        ...
21
        return ( cond ) ? o1 : o2;
22
    }
23
    ...
24
}

Gruß
Markus
Gast #1449713
Lesenswert?

Hallo,

erstmal danke für die Infos!

@Markus
user-defined conversions to or from a base class are not allowed

Die Lösung mit dem Cast passt dafür. Im Prinzip sehe ich das 
Compilerverhalten an der Stelle aber als eher fragwürdig an. Für mich 
ist ein "?" nur die Kurzform von if-else, nicht mehr und nicht weniger 
...
#1450105
Lesenswert?

Alex schrieb:
> Hallo,
>
> erstmal danke für die Infos!
>
> @Markus
> user-defined conversions to or from a base class are not allowed
>
> Die Lösung mit dem Cast passt dafür. Im Prinzip sehe ich das
> Compilerverhalten an der Stelle aber als eher fragwürdig an. Für mich
> ist ein "?" nur die Kurzform von if-else, nicht mehr und nicht weniger
> ...

Vereinfacht gesagt:
? ist ein Ausdruck, der einen Wert zurückliefert
if ist kein Ausdruck, sondern eine Anweisung die keinen Wert 
zurückliefert (im Gegensatz z.B. zum if in Haskell, F#, Smalltalk etc)
Gast #1450761
Lesenswert?

> Die Lösung mit dem Cast passt dafür. Im Prinzip sehe ich das
> Compilerverhalten an der Stelle aber als eher fragwürdig an.

Warum? Ich kenne C# nicht so, aber es ist wohl in der  Hinsicht wie C 
und C++, nämlich daß der Rückgabe-Typ eines Operators aussließlich von 
den übergebenen Argumenten abhängt und nicht davon, was man später mit 
dem zurückgegebenen Wert macht. Und in diesem Fall haben die beiden 
Argumente unterschiedlichen Typ, also müßte eins in den Typ des anderen 
konvertiert werden, was aber nicht geht, da keiner die Basisklasse vom 
anderen ist. Daß du nachher gern ein MyBaseClass hättest, ist dem 
Operator egal.

> Für michist ein "?" nur die Kurzform von if-else, nicht mehr und nicht
> weniger

Was es für dich ist, ist aber von relativ wenig Bedeutung.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren