-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Closed
Description
Language proposal: https://github.com/dotnet/csharplang/blob/main/proposals/csharp-8.0/null-coalescing-assignment.md
LDM notes: https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-07-16.md
Implementation: https://github.com/dotnet/roslyn/tree/features/null-operator-enhancements
- Check language version 8.0
- Upgrade Project available
- Parsing
- parses regardless of language version
- has same precedence as simple assignment
- associativity
-
??=is a token
-
a ??= bis an r-value of typeA, even ifAis nullable andBis not -
amust be a reference type or nullable value type or unconstrained type parameter - Test is
a is null,operator==is ignored - Conversions of
bonly; no conversions ofA- implicit conversion from
BtoAorA0(whereAisA0?) - implicit user-defined conversion from
BtoAorA0-
operatorcan be defined in eitherAorB
-
-
nullconversion -
defaultconversion- test conversion of
defaultis toAnotA0; issue warning since conversion toNullable<A0>was probably not intended
- test conversion of
- implicit conversion from
-
ais an l-value and r-value- by-val or
reflocal, possibly captured - by-val or
refparameter, possibly captured - writable field
- read/write property or readable
refproperty - read/write indexer or readable
refindexer - read/write COM indexed property
- read/write event
-
refreturning invocation - member of
dynamicreceiver -
thisis not allowed, forclassandstruct - pointers are not allowed
- by-val or
-
bis an r-value expression including- by-val or
reflocal, possibly captured - by-val or
refparameter, possibly captured
- by-val or
-
a ?? bis supported for unconstrained type parameters (no reference or value type constraints)-
Ais an unconstrained type parameter andBis implicitly convertible toA, with result typeA -
Ais an unconstrained type parameter andAis implicitly convertible toB, with result typeB -
Ais an unconstrained type parameter andBisdynamic, with result typedynamic
-
-
a ??= bis supported for unconstrained type parameters (no reference or value type constraints)-
Ais an unconstrained type parameter andBis implicitly convertible toA, with result typeA
-
-
awaitis supported withinaandb- with side-effects in
aandb
- with side-effects in
-
ref-
ref a ??= ref b; // error -
ref a ??= b; // error
-
-
inparameter:void M(in object x) { }-
M(a ??= b); // ok -
M(in (a ??= b)); // error
-
-
a ??= throw expris not allowed - Val escape
-
Span<int>? a = expr; a ??= stackAllocIntoSpan;
-
- Flow analysis
- Variables definitely assigned in
aare definitely assigned beforeband after expression - Variables only assigned in
bare not definitely assigned after expression -
out varinbis definitely assigned in remainder ofb, but not definitely assigned after??=
- Variables definitely assigned in
- Lowering
-
a ??= bis lowered totmpA ?? (tmpA = b) - Side-effects are executed exactly once for
a, even ifa ??= bis used as an expression - Side-effects are only executed for
bifaisnull
-
- SemanticModel
-
GetTypeInfoincludes the type and converted type ofb -
IOperation - CFG
-
- IDE
- Auto-formatting does not add space between
??and=
- Auto-formatting does not add space between
Reactions are currently unavailable