Bedingter Ausdruck mit Zieltyp
Anmerkung
Dieser Artikel ist eine Featurespezifikation. Die Spezifikation dient als Designdokument für das Feature. Es enthält vorgeschlagene Spezifikationsänderungen sowie Informationen, die während des Entwurfs und der Entwicklung des Features erforderlich sind. Diese Artikel werden veröffentlicht, bis die vorgeschlagenen Spezifikationsänderungen abgeschlossen und in die aktuelle ECMA-Spezifikation aufgenommen werden.
Es kann einige Abweichungen zwischen der Featurespezifikation und der abgeschlossenen Implementierung geben. Diese Unterschiede werden in den entsprechenden Hinweisen zum Language Design Meeting (LDM) erfasst.
Weitere Informationen zum Prozess für die Aufnahme von Funktions-Speclets in den C#-Sprachstandard finden Sie im Artikel zu den Spezifikationen.
Konvertierung bedingter Ausdrücke
Für einen bedingten Ausdruck c ? e1 : e2
, wenn
- es keinen gemeinsamen Typ für
e1
unde2
gibt oder - für die ein allgemeiner Typ vorhanden ist, aber einer der Ausdrücke
e1
odere2
keine implizite Konvertierung in diesen Typ hat
wir definieren eine neue implizite bedingte Ausdruckskonvertierung, die eine implizite Konvertierung vom bedingten Ausdruck in einen beliebigen Typ T
zulässt, für den es eine Konvertierung von e1
in T
sowie von e2
in T
gibt. Es ist ein Fehler, wenn ein bedingter Ausdruck weder einen gemeinsamen Typ zwischen e1
und e2
hat noch einer Umwandlung durch einen -Ausdruck unterliegt.
Bessere Konvertierung eines Ausdrucks
Wir ändern uns
Bessere Konvertierung eines Ausdrucks
Aufgrund einer impliziten Konvertierung
C1
, die von einem AusdruckE
in einen TypT1
konvertiert, und einer impliziten KonvertierungC2
, die von einem AusdruckE
in einen TypT2
konvertiert, istC1
eine bessere Konvertierung alsC2
, wennE
nicht genauT2
entspricht und mindestens eine der folgenden Bedingungen zutrifft:
Bis
Bessere Konvertierung eines Ausdrucks
Aufgrund einer impliziten Konvertierung
C1
, die von einem AusdruckE
in einen TypT1
konvertiert, und einer impliziten KonvertierungC2
, die von einem AusdruckE
in einen TypT2
konvertiert, istC1
eine bessere Konvertierung alsC2
, wennE
nicht genauT2
entspricht und mindestens eine der folgenden Bedingungen zutrifft:
E
entspricht genauT1
(§12.6.4.5)C1
ist keine Konvertierung bedingter Ausdrücke undC2
ist eine Konvertierung bedingter Ausdrücke.T1
ist ein besseres Konvertierungsziel alsT2
(§12.6.4.7) und entweder sind beideC1
undC2
eine bedingte Ausdruckskonvertierungen oder keine ist eine bedingte Ausdruckskonvertierung.
Cast-Ausdruck
Die aktuelle C#-Sprachspezifikation besagt
Eine cast_expression der Form
(T)E
, bei derT
ein Typ ist undE
eine unary_expression ist, führt eine explizite Konvertierung (§10.3) des Werts vonE
in den TypT
aus.
Bei der bedingten Ausdruckskonvertierung kann es mehrere mögliche Konvertierungen von E
in T
geben. Mit der Hinzufügung von bedingte Ausdruckskonvertierung bevorzugen wir jede andere Konvertierung zu einer bedingte Ausdruckskonvertierung und verwenden die bedingte Ausdruckskonvertierung nur als letztes Mittel.
Designnotizen
Der Grund für die Änderung in Bessere Konvertierung von Ausdruck besteht darin, einen Fall wie diesen zu behandeln:
M(b ? 1 : 2);
void M(short);
void M(long);
Dieser Ansatz hat zwei kleine Nachteile. Zunächst einmal ist es nicht ganz dasselbe wie der Switch-Ausdruck:
M(b ? 1 : 2); // calls M(long)
M(b switch { true => 1, false => 2 }); // calls M(short)
Dies bleibt eine umwälzende Änderung, aber ihr Umfang wird sich wahrscheinlich weniger auf reale Programme auswirken.
M(b ? 1 : 2, 1); // calls M(long, long) without this feature; ambiguous with this feature.
M(short, short);
M(long, long);
Dies wird mehrdeutig, da die Konvertierung in long
für das erste Argument besser ist (da sie nicht die bedingte Ausdruckskonvertierung verwendet), aber die Konvertierung in short
ist besser für das zweite Argument (da short
ein besseres Konvertierungsziel als long
ist). Diese zerbrechende Änderung scheint weniger schwerwiegend zu sein, da sie das Verhalten eines vorhandenen Programms nicht im Stillen ändert.
Der Grund für die Anmerkungen zum Cast-Ausdruck ist, dass ein Fall wie dieser behandelt werden soll:
_ = (short)(b ? 1 : 2);
Dieses Programm verwendet derzeit die explizite Konvertierung von int
in short
, und wir möchten die aktuelle Sprach-Bedeutung dieses Programms beibehalten. Die Änderung wäre zur Laufzeit nicht beobachtbar, aber mit dem folgenden Programm wäre die Änderung feststellbar:
_ = (A)(b ? c : d);
dabei ist c
vom Typ C
, d
vom Typ D
, und es gibt eine implizite benutzerdefinierte Konvertierung von C
in D
, und eine implizite benutzerdefinierte Konvertierung von D
in A
und eine implizite benutzerdefinierte Konvertierung von C
in A
. Wenn dieser Code vor C# 9.0 kompiliert wird und b
wahr ist, konvertieren wir zuerst von c
zu D
und dann zu A
. Wenn wir die bedingte Ausdruckskonvertierung von verwenden, wenn b
wahr ist, dann konvertieren wir direkt von c
zu A
und führen dadurch eine andere Sequenz des Benutzercodes aus. Daher behandeln wir die bedingte Ausdruckskonvertierung als letzte Möglichkeit in einer Umwandlung, um das vorhandene Verhalten beizubehalten.
C# feature specifications