Null-sammankopplingstilldelning
Not
Den här artikeln är en funktionsspecifikation. Specifikationen fungerar som designdokument för funktionen. Den innehåller föreslagna specifikationsändringar, tillsammans med information som behövs under utformningen och utvecklingen av funktionen. Dessa artiklar publiceras tills de föreslagna specifikationsändringarna har slutförts och införlivats i den aktuella ECMA-specifikationen.
Det kan finnas vissa skillnader mellan funktionsspecifikationen och den slutförda implementeringen. Dessa skillnader fångas upp i de relevanta anteckningarna från LDM (Language Design Meeting).
Du kan läsa mer om processen för att införa funktionsspecifikationer i C#-språkstandarden i artikeln om specifikationerna.
Champion-problem: https://github.com/dotnet/csharplang/issues/34
Sammanfattning
Förenklar ett vanligt kodningsmönster där en variabel tilldelas ett värde om det är null.
Som en del av det här förslaget kommer vi också att lätta på typkraven på ??
för att tillåta att ett uttryck vars typ är en obehindrat typparameter används till vänster.
Motivation
Det är vanligt att se formulärets kod
if (variable == null)
{
variable = expression;
}
Det här förslaget lägger till en binär operator som inte kan överbelastas till det språk som utför den här funktionen.
Det har gjorts minst åtta separata community-begäranden för den här funktionen.
Detaljerad design
Vi lägger till en ny form av tilldelningsoperator
assignment_operator
: '??='
;
Som följer de befintliga semantiska reglerna för sammansatta tilldelningsoperatorer (§12.21.4), förutom att vi utelämnar tilldelningen om vänstersidan inte är null. Reglerna för den här funktionen är följande.
Med a ??= b
, där A
är typen av a
, B
är typen av b
, och A0
är den underliggande typen av A
om A
är en nullable värdetyp:
- Om
A
inte finns eller är en värdetyp som inte kan nulliseras uppstår ett kompileringsfel. - Om
B
inte implicit kan konverteras tillA
ellerA0
(omA0
finns) uppstår ett kompileringsfel. - Om
A0
finns ochB
implicit kan konverteras tillA0
, ochB
inte är dynamisk, är typen ava ??= b
A0
.a ??= b
utvärderas under körning som:
Förutom attvar tmp = a.GetValueOrDefault(); if (!a.HasValue) { tmp = b; a = tmp; } tmp
a
bara utvärderas en gång. - Annars är typen av
a ??= b
A
.a ??= b
utvärderas vid körning soma ?? (a = b)
, förutom atta
bara utvärderas en gång.
För att lätta på typkraven för ??
uppdaterar vi specifikationen där det för närvarande står att, med tanke på a ?? b
, där A
är typen av a
:
- Om A finns och inte är en nullbar typ eller en referenstyp uppstår ett kompileringsfel.
Vi kopplar av detta krav för att:
- Om A finns och är en värdetyp som inte kan nulliseras uppstår ett kompileringsfel.
Detta gör att nullkoalesceringsoperatorn kan arbeta med obundna typparametrar, eftersom den obundna typparametern T
finns, inte är en nullbar typ och inte är en referenstyp.
Nackdelar
Precis som med alla språkfunktioner måste vi ifrågasätta om den ytterligare komplexiteten i språket återbetalas i den ytterligare klarhet som erbjuds till brödtexten i C#-program som skulle dra nytta av funktionen.
Alternativ
Programmeraren kan skriva (x = x ?? y)
, if (x == null) x = y;
eller x ?? (x = y)
för hand.
Olösta frågor
- [ ] Bör vi också stödja
&&=
och||=
operatörer?
Designa möten
Ingen.
C# feature specifications