Delen via


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 ais, B het type van bis, en A0 het onderliggende type van A is als A een nullable waarde type is:

  1. Als A niet bestaat of een niet-null-waardetype is, treedt er een compilatietijdfout op.
  2. Als B niet impliciet kan worden omgezet naar A of A0 (als A0 bestaat), treedt er een compilatietijdfout op.
  3. Als A0 bestaat en B impliciet converteerbaar is naar A0en B niet dynamisch is, wordt het type a ??= bA0. a ??= b wordt tijdens runtime geëvalueerd als:
    var tmp = a.GetValueOrDefault();
    if (!a.HasValue) { tmp = b; a = tmp; }
    tmp
    
    Behalve dat a slechts eenmaal wordt geëvalueerd.
  4. Anders is het type a ??= bA. a ??= b wordt tijdens runtime geëvalueerd als a ?? (a = b), behalve dat a 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 ais:

  1. Als A bestaat en geen nulbare of een referentietype is, treedt er een compilatiefout op.

We versoepelen deze vereiste tot:

  1. 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.