csharpstandard icon indicating copy to clipboard operation
csharpstandard copied to clipboard

Null conditional spec seems to no longer disallow `obj?.MethodGroup`

Open jnm2 opened this issue 1 year ago • 17 comments

The original wording of the spec seems to disallow obj?.MethodGroup due to the combination of the following (thanks to @RikkiGibson for finding this):

https://github.com/dotnet/csharplang/blob/main/spec/expressions.md#null-conditional-operator

If E0 is classified as nothing, then E is classified as nothing. Otherwise E is classified as a value.

https://github.com/dotnet/csharplang/blob/main/spec/expressions.md#expression-classifications

Expression classifications

An expression is classified as one of the following:

  • A value. Every value has an associated type.
  • ...
  • A method group, which is a set of overloaded methods resulting from a member lookup (Member lookup)...A method group is permitted in an invocation_expression (Invocation expressions) , a delegate_creation_expression (Delegate creation expressions) and as the left hand side of an is operator, and can be implicitly converted to a compatible delegate type (Method group conversions). In any other context, an expression classified as a method group causes a compile-time error.

This is also the current behavior of the compiler (SharpLab):

using System;
using System.Collections.Generic;

class C
{
    // ❌ CS8978 'method group' cannot be made nullable.
    // (Older compiler: ❌ CS0023 Operator '?' cannot be applied to operand of type 'method group')
    //                             ↓
    Action<int> M(List<int> p) => p?.Add;
}

However, the current spec doesn't contain wording that seems to disallow this. I saw no statement that resembles the one in the original spec:

If E0 is classified as nothing, then E is classified as nothing. Otherwise E is classified as a value.

And reading the entire section as well as the member_access section didn't seem to speak on this at all.

https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#1177-null-conditional-member-access

Rather, the spec says the null-conditional expression has the same meaning as ((object)P == null) ? null : P.A except that P is evaluated once. That conditional expression works for method groups.

jnm2 avatar Oct 27 '22 21:10 jnm2