NULL-Sammelzuweisung
Hinweis
Dieser Artikel ist eine Feature-Spezifikation. 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 Feature-Spezifikation 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.
Champion Issue: https://github.com/dotnet/csharplang/issues/34
Zusammenfassung
Vereinfacht ein gängiges Code-Muster, bei dem einer Variablen ein Wert zugewiesen wird, wenn sie null ist.
Im Rahmen dieses Vorschlags werden wir die Typanforderungen für ??
lockern, damit ein Ausdruck, dessen Typ ein nicht eingeschränkter Typparameter ist, auf der linken Seite verwendet werden kann.
Motivation
Es ist üblich, Code in der Form
if (variable == null)
{
variable = expression;
}
Dieser Vorschlag fügt der Sprache einen nicht überladbaren binären Operator hinzu, der diese Funktion ausführt.
Es gab mindestens acht verschiedene Anfragen aus der Community für diese Funktion.
Detailliertes Design
Wir fügen eine neue Form des Zuweisungsoperators hinzu
assignment_operator
: '??='
;
Dies folgt den vorhandenen semantischen Regeln für zusammengesetzte Zuordnungsoperatoren (§12.21.4), mit der Ausnahme, dass wir die Zuordnung auslassen, wenn die linke Seite nicht null ist. Die Regeln für diese Funktion lauten wie folgt.
Gegeben a ??= b
,wobei A
der Typ von a
,ist B
der Typ von b
, ist und A0
der zugrundeliegende Typ von A
ist, wenn A
ein nullbarer Werttyp ist:
- Wenn
A
nicht existiert oder ein nicht-nullbarer Wertetyp ist, tritt ein Kompilierfehler auf. - Wenn
B
nicht implizit inA
oderA0
konvertierbar ist (wennA0
existiert), tritt ein Kompilierfehler auf. - Wenn
A0
vorhanden ist undB
implizit inA0
konvertierbar ist undB
nicht dynamisch ist, ist der Typ vona ??= b
A0
.a ??= b
wird zur Laufzeit ausgewertet als:
Mit der Ausnahme, dassvar tmp = a.GetValueOrDefault(); if (!a.HasValue) { tmp = b; a = tmp; } tmp
a
nur einmal ausgewertet wird. - Andernfalls ist der Typ von
a ??= b
A
.a ??= b
wird zur Laufzeit wiea ?? (a = b)
ausgewertet, mit dem Unterschied, dassa
nur einmal ausgewertet wird.
Für die Lockerung der Typanforderungen von ??
, aktualisieren wir die Spezifikation, in der es derzeit heißt, dass bei a ?? b
, wobei A
der Typ von a
ist:
- Wenn A existiert und kein nullbarer Typ oder ein Referenztyp ist, tritt ein Kompilierfehler auf.
Wir lockern diese Anforderung:
- Wenn A existiert und ein nicht-nullbarer Werttyp ist, tritt ein Kompilierungszeitfehler auf.
Dies ermöglicht es dem Null-Koaleszenzoperator, mit nicht eingeschränkten Typparametern zu arbeiten, da der nicht eingeschränkte Typparameter T
existiert, kein nullbarer Typ ist und kein Verweistyp ist.
Nachteile
Wie bei jeder Sprachfunktion müssen wir uns fragen, ob die zusätzliche Komplexität der Sprache durch die zusätzliche Klarheit gerechtfertigt ist, die der Gesamtheit der C#-Programme geboten wird, die von der Funktion profitieren würden.
Alternativen
Der Programmierer kann (x = x ?? y)
, if (x == null) x = y;
oder x ?? (x = y)
manuell schreiben.
Ungelöste Fragen
- [ ] Sollten wir auch
&&=
und||=
Operatoren unterstützen?
Designbesprechungen
Keine.
C# feature specifications