Freigeben über


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

  1. es keinen gemeinsamen Typ für e1 und e2 gibt oder
  2. für die ein allgemeiner Typ vorhanden ist, aber einer der Ausdrücke e1 oder e2 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 Ausdruck E in einen Typ T1 konvertiert, und einer impliziten Konvertierung C2, die von einem Ausdruck E in einen Typ T2 konvertiert, ist C1 eine bessere Konvertierung als C2, wenn E nicht genau T2 entspricht und mindestens eine der folgenden Bedingungen zutrifft:

Bis

Bessere Konvertierung eines Ausdrucks

Aufgrund einer impliziten Konvertierung C1, die von einem Ausdruck E in einen Typ T1 konvertiert, und einer impliziten Konvertierung C2, die von einem Ausdruck E in einen Typ T2 konvertiert, ist C1 eine bessere Konvertierung als C2, wenn E nicht genau T2 entspricht und mindestens eine der folgenden Bedingungen zutrifft:

  • E entspricht genau T1 (§12.6.4.5)
  • C1 ist keine Konvertierung bedingter Ausdrücke und C2 ist eine Konvertierung bedingter Ausdrücke.
  • T1 ist ein besseres Konvertierungsziel als T2 (§12.6.4.7) und entweder sind beide C1 und C2 eine bedingte Ausdruckskonvertierungen oder keine ist eine bedingte Ausdruckskonvertierung.

Cast-Ausdruck

Die aktuelle C#-Sprachspezifikation besagt

Eine cast_expression der Form (T)E, bei der T ein Typ ist und E eine unary_expression ist, führt eine explizite Konvertierung (§10.3) des Werts von E in den Typ T 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 Aund 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.