Roslyn: Proposal: Allow Null-conditional operators to be lvalues

Created on 21 Sep 2016  路  7Comments  路  Source: dotnet/roslyn

Currently you cannot assign a value to an object's property if that property may be null.

I suggest to allow for the Null-conditional operator to become an lvalue.

This would allow for the following statement to compile without error:

``` c#
System.Web.HttpContext.Current?.Response.StatusCode = 200;

#### Everything right to a runtime null value is suggested not to be executed/evaluated.

So at run-time, the following two statements would be equivalent, given that any of the Null-conditional operator yielded `null`:

``` c#
// GetCounterAndIncrement() is not getting called if myObject or NullableProperty yields null
myObject?.NullableProperty?.intProperty = GetCounterAndIncrement();

// equivalent
if (myObject != null && myObject.NullableProperty != null)
  myObject.NullableProperty.intProperty = GetCounterAndIncrement();

... same for function calls:

``` c#
// GetCounterAndIncrement() is not getting called if myObject or NullableProperty yields null
GetMyObject()?.NullableProperty?.intProperty = GetCounterAndIncrement();

// equivalent
if ((var temp = GetMyObject()) != null && temp.NullableProperty != null)
temp.NullableProperty.intProperty = GetCounterAndIncrement();
```

RFC

Area-Language Design

Most helpful comment

  1. As a language proposal, this should probably go to csharplang. Paging @jcouv as he's good at moving these.
  2. A big part of ?. is not executing code once null is hit. i.e. if i have:

x?.Foo(a1, b1, c1) then a1, b1, c1 are not evaluated if x is null. It seems strange that in x?.y = z that z would be evaluated if it's not going to be assigned into anything.

All 7 comments

myObject?.NullableProperty.intProperty = GetCounterAndIncrement();

It looks strange... Should you get null reference exception if myObject is null?

I think we could translate the assignment operator of the form:

var result = (expression?.Member = value);

to a ternary of the form:

var temp = expression;
var result = (temp != null ? (temp.Member = value) : fallbackValue);
  • If type of the assignment expression is nullable, fallbackValue is emitted as default(T) where T is the type of that expression.
  • If type of the assignment expression is non-nullable, fallbackValue is emitted as default(T?) where T is the type of that expression.

Similarly, we may use -= and += (event subscription and unsubscription) operators with a conditional access on the left-hand-side (#1276), but in that case, the resultant type of the whole expression is void just like var x = obj?.Event += handler; // ERROR as you can't assign void.

This could be extended to conditional indexer access or other compound assignments too.

@hardhub: 馃憤 馃槼

Oops ... Edited my original posting to show expected behaviour. Thanks for pointing it out!

  1. As a language proposal, this should probably go to csharplang. Paging @jcouv as he's good at moving these.
  2. A big part of ?. is not executing code once null is hit. i.e. if i have:

x?.Foo(a1, b1, c1) then a1, b1, c1 are not evaluated if x is null. It seems strange that in x?.y = z that z would be evaluated if it's not going to be assigned into anything.

Moving to csharplang

Issue moved to dotnet/csharplang #1106 via ZenHub

Was this page helpful?
0 / 5 - 0 ratings