C# und ternärer Operator

Gast #1449485
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
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
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
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 
...
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
> 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

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.