Warum ist dieser Code in C # ungültig?
Folgende code wird nicht kompiliert:
string foo = "bar";
Object o = foo == null ? DBNull.Value : foo;
Bekomme ich: Fehler 1 der Typ des bedingten Ausdrucks kann nicht bestimmt werden, denn es gibt keine implizite Konvertierung zwischen " System.DBNull' und 'string'
Um dies zu beheben, muss ich tun so etwas wie dieses:
string foo = "bar";
Object o = foo == null ? DBNull.Value : (Object)foo;
Dieser Besetzung scheint sinnlos, da dies sicherlich zu Recht:
string foo = "bar";
Object o = foo == null ? "gork" : foo;
Scheint es mir, dass, wenn die ternäre Verzweigungen sind von verschiedenen Arten, wird der compiler nicht autobox die Werte für das type-Objekt...aber wenn Sie vom gleichen Typ sind dann die autoboxing automatisch.
In meinem Kopf die erste Anweisung sollte legal sein...
Kann mir jemand beschreiben, warum der compiler dies nicht erlaubt, und warum die Entwickler von C# entschieden, dies zu tun? Ich glaube, dies ist legal in Java...Obwohl ich nicht bestätigt haben.
Dank.
EDIT: bitte ich um ein Verständnis dafür, warum Java und C# behandeln Sie diese anders, was Los ist hinter den kulissen in C# machen diesen ungültig. Ich weiß, wie Sie ternär, und bin nicht auf der Suche nach einem "besseren Weg" zum code der Beispiele. Ich verstehe die Regeln des ternären in C#, aber ich will wissen, WARUM...
BEARBEITEN (Jon Skeet): Entfernt "autoboxing" - tag, da keine Boxen beteiligt ist, in dieser Frage.
InformationsquelleAutor der Frage mmattax | 2008-10-14
Du musst angemeldet sein, um einen Kommentar abzugeben.
Der compiler erfordert, dass entweder die Typen des zweiten und Dritten Operanden gleich sind, oder dass man implizit Cabrio zu den anderen. In Ihrem Fall, die Typen sind DBNull und Zeichenfolge, weder die implizit Cabrio zu den anderen. Casting-entweder von Ihnen zu Objekt löst.
EDIT: wie es Aussieht, ist in der Tat legal in Java. Ganz, wie es funktioniert, was zu tun ist, wenn es um die Methode überladen, ich bin mir nicht sicher... ich habe gerade geschaut bei der JLS, und es ist äußerst unklar, was die Art der bedingten ist, wenn es zwei inkompatible Referenz-Typen beteiligt. Der C# - Art zu arbeiten kann mehr reizt gelegentlich, aber es ist übersichtlicher IMO.
Entsprechenden Abschnitt des C# - 3.0-Spezifikation ist 7.13, dass der bedingte operator:
InformationsquelleAutor der Antwort Jon Skeet
DBNull.Value
zurück gebenDBNull
.Du willst, der Typ, der
string
.Während
string
werden kannnull
es kann nichtDBNull
.In Ihrem code die Anweisung auf der rechten Seite von dem Gleichheitszeichen wird ausgeführt, bevor die Zuordnung zu dem Objekt.
Grundsätzlich wenn Sie:
In .Net sowohl der wahren und falschen Optionen müssen implizit Cabrio auf die gleiche Art, vor was auch immer Sie ordnen Sie zu.
Dies ist ein Ergebnis, wie C# beschäftigt sich mit Typ-Sicherheit. Zum Beispiel gilt:
C#3 keine Unterstützung für dynamische Typen, die so was testen??? In C# jede Aufgabe ist auch eine Anweisung mit einem Rückgabewert, so dass, obwohl die
var
Konstrukt ist neu in C#3 die Aussage auf der rechten Seite des ist-gleich immer zu lösen hat, um einen einzigen Typ.In C#4 und höher können Sie explizit die Unterstützung dynamischer Typen, aber ich denke nicht, dass das hilft.
InformationsquelleAutor der Antwort Keith
Übrigens, dein code ist ein spezieller Fall, dass Sie nicht bei der Bedingungsoperator überhaupt. Stattdessen wird der null coalesce operator ist besser geeignet (aber immer noch erfordert Gießen):
InformationsquelleAutor der Antwort Konrad Rudolph