dotnet / dotnet/csharpstandard
Null conditional spec seems to no longer disallow `obj?.MethodGroup`
- Dominant language
- C#
- Stars
- 815
- Forks
- 99
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 16
Description
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](expressions.md#member-lookup))...A method group is permitted in an _invocation_expression_ ([Invocation expressions](expressions.md#invocation-expressions)) , a _delegate_creation_expression_ ([Delegate creation expressions](expressions.md#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](conversions.md#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](https://sharplab.io/#v2:C4LgbgpgTglgZgTwD4AEBMBGAsAKBQBgAIUMAWAbl13UIGFcBvXQlwgejcMBlyOgZQA4AnAHZ+hAOQBbCMAAWAewAmhAOZR5AVwAO4wgGMAhgDsj84IQBGEQpIOLrRjQBsnBi04gA6Zqw6t/AYFB/oDJhD4sJGgAPDBGwAB8hACyABQAMjAAzsAxcYlaAJSEALz5APyeAIKKipQ4AL5AA===)):
```cs
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 M(List 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.
Contributor guide
Assessment
This issue has not been assessed yet.