[Proposal]: Allow nameof to always access instance members from static context (VS 17.7, .NET 8)
- Dominant language
- C#
- Stars
- 12.7k
- Forks
- 1.1k
- Avg merge
- 11h 1m
- Merged PRs (30d)
- 3
Description
# Allow nameof to always access instance members from static context
* [x] Proposed
* [x] Prototype: Done
* [x] Implementation: Done
* [ ] Specification: Not Started
## Summary
[summary]: #summary
For background see https://github.com/dotnet/roslyn/pull/48754
The current compiler has some interesting behavior with regards to accessing instance members from a static context:
```csharp
using System;
public struct C {
public string P;
public static string M1() => nameof(P); // Legal
public static string M2() => nameof(P.Length); // error CS0120: An object reference is required for the non-static field, method, or property 'C.P'
}
```
Where even though `P` is an instance member you can access it from a static context, but you can't access `P.Length`.
The relevant part of the spec is [this](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#nameof-expressions):
> The meaning of the named_entity of a nameof_expression is the meaning of it as an expression; that is, either as a simple_name, a base_access or a member_access. However, where the lookup described in Simple names and Member access results in an error because an instance member was found in a static context, a nameof_expression produces no such error.
This is somewhat ambiguous, but can be interpreted as saying only the top level lookup ignores errors where an instance member was found in a static context, but nested lookups do not. See here https://github.com/dotnet/roslyn/pull/48754#issuecomment-712295307.
My request here is twofold:
1. Firstly can the LDT clarify the meaning of the spec here.
2. If the current behavior is not a bug, can we allow this in a future language version.
## Motivation
[motivation]: #motivation
1. Remove a strange and confusing inconsistency in what's allowed.
2. Attribute arguments are considered a static context, and accessing instance members is often useful in them, e.g. when using the ForeignKeyAttribute.
## Detailed design
[design]: #detailed-design
Update the spec from:
> The meaning of **the named_entity of a nameof_expression** is the meaning of it as an expression; that is, either as a simple_name, a base_access or a member_access. However, where the lookup described in Simple names and Member access results in an error because an instance member was found in a static context, a nameof_expression produces no such error.
To
> The meaning of **a named_entity** is the meaning of it as an expression; that is, either as a simple_name, a base_access or a member_access. However, where the lookup described in Simple names and Member access results in an error because an instance member was found in a static context, a nameof_expression produces no such error.
## Drawbacks
[drawbacks]: #drawbacks
This is not a particularly common scenario, and so probably not worth changing the spec for, if it's decided that the current implementation is not a bug.
## Alternatives
[alternatives]: #alternatives
## Unresolved questions
[unresolved]: #unresolved-questions
## Design meetings
https://github.com/dotnet/csharplang/blob/master/meetings/2020/LDM-2020-11-11.md#allow-nameof-to-access-instance-members-from-static-contexts
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.