dotnet / dotnet/csharplang

[Proposal]: Allow nameof to always access instance members from static context (VS 17.7, .NET 8)

Open
#4,037 9 comments 30 reactions 1 assignee Assigned to @333fred View on GitHub
Implemented Needs ECMA Spec Proposal Proposal champion
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.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.