C#6 null conditional operator as a code toggler?

I already know that the null-conditional operator can be used to test for null before performing a member access.

for example :

 int? length = customers?.Length; // null if customers is null 
 Customer first = customers?[0];

If customers is null in customers?.Length , then customers?.Length will return null and that null will be in int? length = ... variable

I also know that it can be used for a single atomic operation of method invocation in a multithreaded environment :

public void OnFoo()
{
    Foo?.Invoke(this, EventArgs.Empty);
}

But

AFAIU - if Foo is null then

 Foo?.Invoke(this, EventArgs.Empty);

Is also null

And so we're left with

public void OnFoo()
{
    null; //compilation error
}

And so I ask :

Question

it seems that the null-conditional operator is not only for testing null and if there is , then it moves on deeper : x?.y?.c?.d -

but it is also act like code toggle :

Like this:

  public void OnFoo()
    {
        Foo?.Invoke(this, EventArgs.Empty); //Let's assume Foo =null;
    }

Becomes

  public void OnFoo()
    {

    }

Am I right? I didn't find any documentation to that aspect.

Jon Skeet
people
quotationmark

The null conditional operator is an operator which results in an expression - it's not a statement.

Your logic about Foo?.Invoke(this, EventArgs.Empty) being equivalent to null doesn't really hold, as it seems to assume a sort of "template replacement" which doesn't apply.

The type of the expression

Foo?.Invoke(this, EventArgs.Empty)

is nothing, because Invoke has a void return type. You can't write:

// Invalid
var result = Foo?.Invoke(this, EventArgs.Empty);

This is just like in 7.6.5 of the C# 5 specification:

The result of evaluating an invocation-expression is classified as follows:

  • If the invocation-expression invokes a method or delegate that returns void, the result is nothing. An expression that is classified as nothing is permitted only in the context of a statement-expression (§8.6) or as the body of a lambda-expression (§7.15). Otherwise a binding-time error occurs.
  • Otherwise, the result is a value of the type returned by the method or delegate.

A member invocation can use a null conditional operator, at which point the invocation is only performed when the primary expression evaluates to a non-null value. The result of an invocation expression involving a null conditional operator is the same as it would be with a regular . operator, except that if the result would be a non-nullable value type, the result with the null conditional operator is the corresponding nullable value type.

All of this will be put a lot more precisely when the C# 6 specification comes out, of course - but I don't know when that will be. (I don't think there's a C# 6 spec at the moment. I'm sure there's one internally in MS, but not a public one. As the ECMA standardization process is getting closer for standardizing C# 5, that could potentially impact the release process for C# 6.)

people

See more on this question at Stackoverflow