csharpstandard
csharpstandard copied to clipboard
Null conditional spec seems to no longer disallow `obj?.MethodGroup`
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.