Toewijzing null-samenvoegen
Notitie
Dit artikel is een functiespecificatie. De specificatie fungeert als het ontwerpdocument voor de functie. Het bevat voorgestelde specificatiewijzigingen, samen met informatie die nodig is tijdens het ontwerp en de ontwikkeling van de functie. Deze artikelen worden gepubliceerd totdat de voorgestelde specificaties zijn voltooid en opgenomen in de huidige ECMA-specificatie.
Er kunnen enkele verschillen zijn tussen de functiespecificatie en de voltooide implementatie. Deze verschillen worden vastgelegd in de relevante notities van de Language Design Meeting (LDM) .
Meer informatie over het proces voor het aannemen van functiespeclets in de C#-taalstandaard vindt u in het artikel over de specificaties.
Probleem met kampioen: https://github.com/dotnet/csharplang/issues/34
Samenvatting
Vereenvoudigt een gemeenschappelijk coderingspatroon waarbij aan een variabele een waarde wordt toegewezen als deze null is.
Als onderdeel van dit voorstel zullen we ook de typevereisten voor ??
versoepelen, zodat een expressie waarvan het type een onbeperkte typeparameter is, aan de linkerkant kan worden gebruikt.
Motivatie
Het is gebruikelijk om code van het formulier te zien
if (variable == null)
{
variable = expression;
}
Dit voorstel voegt een niet-overbelastingbare binaire operator toe aan de taal die deze functie uitvoert.
Er zijn ten minste acht afzonderlijke communityaanvragen voor deze functie.
Gedetailleerd ontwerp
We voegen een nieuwe vorm van toewijzingsoperator toe
assignment_operator
: '??='
;
Dit volgt de bestaande semantische regels voor samengestelde toewijzingsoperatoren (§12.21.4), behalve dat we de toewijzing verwijderen als de linkerkant niet null is. De regels voor deze functie zijn als volgt.
Gegeven a ??= b
, waarbij A
het type van a
is, B
het type van b
is, en A0
het onderliggende type van A
is als A
een nullable waarde type is:
- Als
A
niet bestaat of een niet-null-waardetype is, treedt er een compilatietijdfout op. - Als
B
niet impliciet kan worden omgezet naarA
ofA0
(alsA0
bestaat), treedt er een compilatietijdfout op. - Als
A0
bestaat enB
impliciet converteerbaar is naarA0
enB
niet dynamisch is, wordt het typea ??= b
A0
.a ??= b
wordt tijdens runtime geëvalueerd als:
Behalve datvar tmp = a.GetValueOrDefault(); if (!a.HasValue) { tmp = b; a = tmp; } tmp
a
slechts eenmaal wordt geëvalueerd. - Anders is het type
a ??= b
A
.a ??= b
wordt tijdens runtime geëvalueerd alsa ?? (a = b)
, behalve data
slechts eenmaal wordt geëvalueerd.
Voor de verruiming van de typevereisten van ??
, werken we de specificatie bij, waar momenteel wordt vermeld dat, gegeven a ?? b
, waarbij A
het type van a
is:
- Als A bestaat en geen nulbare of een referentietype is, treedt er een compilatiefout op.
We versoepelen deze vereiste tot:
- Als A bestaat en een niet-null-waardetype is, treedt er een compilatietijdfout op.
Hierdoor kan de null-coalescing operator werken met onbeperkte typeparameters, omdat de onbeperkte typeparameter T
bestaat, geen nullbaar type is en geen referentietype is.
Nadelen
Net als bij elke taalfunctie moeten we ons afvragen of de extra complexiteit voor de taal wordt terugbetaald in de aanvullende duidelijkheid die wordt geboden aan de hoofdtekst van C#-programma's die zouden profiteren van de functie.
Alternatieven
De programmeur kan (x = x ?? y)
, if (x == null) x = y;
of x ?? (x = y)
handmatig schrijven.
Niet-opgeloste vragen
- [ ] Moeten we ook
&&=
en||=
operators ondersteunen?
Ontwerpvergaderingen
Geen.
C# feature specifications