Die Spezifikation (§7.14) besagt, dass es für den bedingten Ausdruck b ? x : ydrei Möglichkeiten gibt, entweder xund ybeide haben einen Typ und bestimmte gute Bedingungen sind erfüllt, nur eine von xund yhat einen Typ und bestimmte gute Bedingungen sind erfüllt, oder ein Fehler bei der Kompilierung tritt ein. Hier bedeutet "bestimmte gute Bedingungen", dass bestimmte Konvertierungen möglich sind, auf die wir im Folgenden näher eingehen werden.
Wenden wir uns nun dem deutschen Teil der Spezifikation zu:
Wenn nur einer von xund yeinen Typ hat und beide xund yimplizit in diesen Typ konvertierbar sind, dann ist dies der Typ des bedingten Ausdrucks.
Das Problem hier ist, dass in
int? number =true?5:null;
Nur eines der bedingten Ergebnisse hat einen Typ. Hier xist eine intwörtliche, und yist nulldie sich nicht einen Typ haben und nullist nicht implizit konvertierbar zu einem int1 . Daher werden "bestimmte gute Bedingungen" nicht erfüllt, und es tritt ein Fehler bei der Kompilierung auf.
Es gibt zwei Möglichkeiten, dies zu umgehen:
int? number =true?(int?)5:null;
Hier sind wir noch in dem Fall, dass nur einer von xund yeinen Typ hat. Beachten Sie, dassnull nach wie vor nicht über eine Art noch der Compiler habe kein Problem mit diesem , weil (int?)5und nullbeide implizit konvertierbar int?(§ 6.1.4 und §6.1.5).
Der andere Weg ist offensichtlich:
int? number =true?5:(int?)null;
aber jetzt müssen wir a lesen andere Klausel in der Spezifikation zu verstehen, warum dies in Ordnung ist:
Wenn xhat Typ Xundy hat Typ Ydann
Wenn eine implizite Konvertierung (§6.1) von Xbis Y, aber nicht von Ybis bestehtX , Yist dies der Typ des bedingten Ausdrucks.
Wenn eine implizite Konvertierung (§6.1) von Ybis X, aber nicht von Xbis bestehtY , Xist dies der Typ des bedingten Ausdrucks.
Andernfalls kann kein Ausdruckstyp ermittelt werden, und es tritt ein Fehler bei der Kompilierung auf.
Hier xist vom Typ intund yist vom Typ int?. Es gibt keine implizite Konvertierung von int?nach int, aber es gibt eine implizite Konvertierung von intnach, int?so dass der Typ des Ausdrucks ist int?.
1 : Beachten Sie ferner, dass der Typ der linken Seite bei der Bestimmung des Typs des bedingten Ausdrucks ignoriert wird, was hier häufig zu Verwirrung führt.
Gutes Zitat der Spezifikation, um zu veranschaulichen, warum dies passiert - +1!
JerKimball
7
Eine andere Option ist new int?()anstelle von (int?)null.
Guvante
1
Dies ist auch der Fall, wenn Sie einen nullbaren Datenbankfeldtyp haben, z. B. eine nullbare DateTime, und Sie versuchen, Daten zu übertragen DateTime, wenn dies erforderlich ist(DateTime?)
Mike Upjohn
73
null hat keinen identifizierbaren Typ - es muss nur ein wenig gestoßen werden, um glücklich zu werden:
Das Problem ist nicht, dass nulles keinen identifizierbaren Typ gibt. Das Problem ist, dass es keine implizite Konvertierung von nullnach gibt int. Details hier .
Jason
das interessante ist das int? number = true ? 5 : (int?)null;und int? number = true ? (int?)5 : null;beide kompilieren !! Scratch, Scratch
Davidhq
2
Ich beschreibe in meiner Antwort genau, warum dies passiert .
Jason
4
Wie andere bereits erwähnt haben, ist die 5 eine intund nullkann nicht implizit in konvertiert werdenint .
Hier sind andere Möglichkeiten, um das Problem zu umgehen:
int? num =true?5:default(int?);int? num =true?5:newint?();int? num =true?5:nullasint?;int? num =true?5:(int?)null;int? num =true?(int?)5:null;int? num =true?5asint?:null;int? num =true?newint?(5):null;
Auch überall, wo Sie sehen int?, können Sie auch verwenden Nullable<int>.
Manchmal bedingt ?? und ?: Ausdrücke haben keinen offensichtlichen gemeinsamen Typ zwischen den Zweigen. Solche Fälle schlagen heute fehl, aber C # 9.0 lässt sie zu, wenn es einen Zieltyp gibt, in den beide Zweige konvertieren:
Person person = student ?? customer;// Shared base typeint? result = b ?0:null;// nullable value type
Antworten:
Die Spezifikation (§7.14) besagt, dass es für den bedingten Ausdruck
b ? x : y
drei Möglichkeiten gibt, entwederx
undy
beide haben einen Typ und bestimmte gute Bedingungen sind erfüllt, nur eine vonx
undy
hat einen Typ und bestimmte gute Bedingungen sind erfüllt, oder ein Fehler bei der Kompilierung tritt ein. Hier bedeutet "bestimmte gute Bedingungen", dass bestimmte Konvertierungen möglich sind, auf die wir im Folgenden näher eingehen werden.Wenden wir uns nun dem deutschen Teil der Spezifikation zu:
Das Problem hier ist, dass in
Nur eines der bedingten Ergebnisse hat einen Typ. Hier
x
ist eineint
wörtliche, undy
istnull
die sich nicht einen Typ haben undnull
ist nicht implizit konvertierbar zu einemint
1 . Daher werden "bestimmte gute Bedingungen" nicht erfüllt, und es tritt ein Fehler bei der Kompilierung auf.Es gibt zwei Möglichkeiten, dies zu umgehen:
Hier sind wir noch in dem Fall, dass nur einer von
x
undy
einen Typ hat. Beachten Sie, dassnull
nach wie vor nicht über eine Art noch der Compiler habe kein Problem mit diesem , weil(int?)5
undnull
beide implizit konvertierbarint?
(§ 6.1.4 und §6.1.5).Der andere Weg ist offensichtlich:
aber jetzt müssen wir a lesen andere Klausel in der Spezifikation zu verstehen, warum dies in Ordnung ist:
Hier
x
ist vom Typint
undy
ist vom Typint?
. Es gibt keine implizite Konvertierung vonint?
nachint
, aber es gibt eine implizite Konvertierung vonint
nach,int?
so dass der Typ des Ausdrucks istint?
.1 : Beachten Sie ferner, dass der Typ der linken Seite bei der Bestimmung des Typs des bedingten Ausdrucks ignoriert wird, was hier häufig zu Verwirrung führt.
quelle
new int?()
anstelle von(int?)null
.DateTime
, wenn dies erforderlich ist(DateTime?)
null
hat keinen identifizierbaren Typ - es muss nur ein wenig gestoßen werden, um glücklich zu werden:quelle
int? number = true ? 5 : null as int?;
null
es keinen identifizierbaren Typ gibt. Das Problem ist, dass es keine implizite Konvertierung vonnull
nach gibtint
. Details hier .int? number = true ? 5 : (int?)null;
undint? number = true ? (int?)5 : null;
beide kompilieren !! Scratch, ScratchWie andere bereits erwähnt haben, ist die 5 eine
int
undnull
kann nicht implizit in konvertiert werdenint
.Hier sind andere Möglichkeiten, um das Problem zu umgehen:
Auch überall, wo Sie sehen
int?
, können Sie auch verwendenNullable<int>
.quelle
In
C# 9
diesem Blog ist jetzt erlaubtOder dein Beispiel:
quelle