# C# Language Design Meeting for March 4th, 2024

## Agenda

- [Breaking changes: making `field` and `value` contextual keywords](#breaking-changes-making-field-and-value-contextual-keywords)
- [Overload resolution priority](#overload-resolution-priority)

## Quote of the Day

- "I think it's actually a good think to have that onericity. Onericity? I think that's a word I just made up."

## Discussion

### Breaking changes: making `field` and `value` contextual keywords

https://github.com/dotnet/csharplang/issues/7964  
https://github.com/dotnet/csharplang/issues/7918

We started today by exploring a piece of community feedback on the previous proposal for introducing breaking changes: what if, instead of trying to make `field` behave like `value` does today, we try
to make it a contextual keyword when in a property accessor? One thing that became clear here, after multiple discussion directions, was that we needed to determine what the most important bit to the LDM
is here: is it most important to the LDM that `field` behaves identically to `value` (whether that's as a contextual keyword or an implicit parameter), or can we view them as unrelated concepts? We mostly
think the former, but there are some members of the LDM that would prefer to have `field` have their desired semantics, even if that means it differs from `value`. There is a potential that, by changing
`value`, we will break a concept that is understood by a large number of our users. We do hear more about people misunderstanding the meaning of `value` than not, but this could simply be a biased opinion
because we only ever hear the complaints.

We then turned to talking about the advantages and disadvantages of using contextual keywords in these scenarios, and how broad we want to make the context. A number of LDM members were happy with the
fairly constrained scope of the breaks and fixes here, and think that they end up being fairly straightforward. There are a few interesting wrinkles that need to be worked out:

* What is the behavior of `nameof(value)`? Today, it's the string `"value"`, `value` is actually a parameter named `value`. We didn't arrive at a concrete conclusion on this today.
* How does this behave for indexers? `value` is a legal parameter for get-only indexers, does it need to remain so? And does it need to continue to be illegal for settable properties? We also did not arrive
  at a conclusion for this today.

After discussion, we are most in favor of `field` and `value` as contextual keywords. We then discussed the scope of this: does every usage of `field` and `value` within a property need to be escaped, just
the simple names, or somewhere in between? The example we looked at for these is:

```cs
int Prop
{
    get
    {
        int field = 1; // If it's only simple names that need to be escaped, this is legal
        field = 2; // This needs to be escaped in every version; are we ok with the inconsistency between declaration and usage?
        this.field = 3; // This is unambiguous, but does it need to be escaped anyways?
    }
}
```

We ended up with 3 options:

1. Only simple names need to be escaped. `int field = 1` is legal, as is `this.field`, but `field = 2` would need to be escaped to refer to the local or class field.
2. Simple names and declarations need to be escaped. `int field = 1;` needs to be escaped, but `this.field` does not.
3. All usages need to be escaped. Both `int field = 1;` and `this.field` need to be escaped.

Consistency is again a key point here. Existing contextual keywords, such as `await` within an `async` method body, must always be escaped, no matter how it's used. `this.await`, for example, must be
written as `this.@await`. This ultimately convinced us that option 3 is right: if the goal here is to take breaks to make the language simpler, let's not introduce another set of rules around when a
contextual keyword is legal to use unescaped.

#### Conclusion

We will move forward with the proposal to treat `field` and `value` as contextual keywords. We will treat them as contextual keywords in all usages within accessor bodies. More work will need to be done
to determine the behavior of indexers, `nameof(value)`, and whether `value` is a contextual keyword within a `get` body.

### Overload resolution priority

https://github.com/dotnet/csharplang/issues/7706  
https://github.com/dotnet/csharplang/pull/7906/commits/aa6ab11c7df001e807e956f5b056785588e8b12e

Finally today, we took a brief look at the proposal for overload resolution priority. We've previously looked at it in the form of `BinaryCompatOnlyAttribute`, but some particularly gnarly challenges
with OHI convinced us that it was not the right approach. Instead, we went with a narrower approach of allowing an API author to adjust the relative priority of their methods to ensure that something
that is better for a given domain, such as the `Debug.Assert` overload that takes a `CallerArgumentExpressionAttribute`, is preferred over what C# would normally choose. The LDM appreciated the specificity
and narrow target of the new proposal, though there are likely some finer details to work out with where exactly the specification needs to be modified, and how it will interact with extension lookup in
the new extension type world. We also did a quick dive on some of the open questions around inheritance with this new attribute: with the exception of a few things like parameter names and default values,
the original definition of a virtual method is always the one used for determining applicability, and it seems likely that we'd want to do the same here, and not allow derived overrides to change the
priority of a member; we did not concretely decide this, however, so we'll need to confirm when implementation starts.

#### Conclusion

Proposal is approved, and we'll work on it in the upcoming development cycle.
