# C# Language Design Meeting for March 10th, 2025

## Agenda

- [Extensions](#extensions)
    - [Property method calling](#property-method-calling)
    - [Scoping and Shadowing](#scoping-and-shadowing)
    - [Type parameter inferrability](#type-parameter-inferrability)
    - [Accessibility](#accessibility)

## Quote of the Day

- "We're starting the boring part of the meeting now"

## Discussion

### Extensions

Champion issue: https://github.com/dotnet/csharplang/issues/8697  
Specification: https://github.com/dotnet/csharplang/blob/82157ff229f6c1bd2954a96ec2acb47064a48bad/proposals/extensions.md

We looked at a few questions in extensions today.

#### Property method calling

The first question we looked at was whether to allow extension property underlying methods to be called directly on an instance. For
example:

```cs
_ = new object().Prop; // Allowed
_ = C.get_Prop(new object()); // Previously said this is allowed
_ = new object().get_Prop(); // Should this be allowed?

public static class C
{
    extension (object o)
    {
        public int Prop { get => 1; }
    }
}
```

We're not sure what the use case for this form is. We allow the `get_Prop` syntax on `C` itself to serve as a disambiguation syntax, but
we don't know why `get_Prop` should be visible as a method on `object` itself. We don't do this for regular properties, so we don't have a
reason to allow it for extension properties either. Given this, we will disallow it.

##### Conclusion

`get_Prop` form is disallowed in extension method form.

#### Scoping and Shadowing

Next, we looked at a couple of questions around scoping and shadowing. First, should extension parameter names be in scope in static
members, even if they'd be an error to reference, and even if they shadow a field? And second, should instance methods be able to shadow
the extension parameter in their own parameter lists? As an example:

```cs
public static class E
{
    static string s;
    extension(string s)
    {
        public int M(int i)
        {
            return s.Length + i;
        }
        public static string P => s; // Does this error that the extension parameter s can't be used, or bind to E.s?
        public void M2(string s) { ... } // Should we allow this to shadow the extension parameter?
        public static void M3(string s) { ... } // Should we allow this to shadow the extension parameter, since there's no implicit s?
        public static void M4() { s.ToString(); } // Does this bind to the extension receiver parameter and error, or to E.s?
    }
}
```

There are a couple of sets of rules we can look to for inspiration here: existing parameter rules, and primary constructor rules. After
some thought, we think existing parameter rules are the right inspiration; as mentioned in the previous topic, we keep leaning further
towards the extension block being just another parameter. This means it should follow the same rules for other parameters, and when we
consider instance extension methods, `M2` isn't shadowing anything, it's literally declaring 2 parameters with the same name, which is just
not permitted by C#'s rules. On the other hand, local functions or lambdas inside `M2` would be allowed to shadow the parameter `s`, just
like they can with other parameters today.

More interesting is the `static` question: should we allow the parameter list in a `static` member to shadow the extension parameter?
The LDM is fairly split here between allowing or disallowing it. We therefore think we'll start most restrictive, disallowing the parameter
list to shadow, and wait for feedback. There is a workaround for users who want to do this, as they can just declare a new parameterless
extension block and declare the method in that block, so this isn't a hard blocker for code, but we'd rather start as more restrictive and
loosen when we have real examples, rather than starting with a loose rule that we may regret later.

##### Conclusion

Extension block parameters will be lexically in scope in all members declared within the block, and will be treated as if they were declared
in the parameter list of each extension member for the purposes of naming collisions and shadowing.

#### Type parameter inferrability

Question: https://github.com/dotnet/csharplang/blob/82157ff229f6c1bd2954a96ec2acb47064a48bad/proposals/extensions.md#extension-declaration-validation (first bullet)

We next looked at whether we should loosen the requirement that any type parameters in the extension block declaration had to be inferrable
from the extension parameter. We don't think that we have the examples that would be necessary to lift this restriction today: we can think
of a couple of hypotheticals, such as an out-of-order `TResult, TSource`, or a set of type parameters where `TSource` needed to be
constrained based on `TResult`, but we don't have any concrete examples of this. Given that, we think we should start most restrictive, and
wait for users to bring examples to us.

##### Conclusion

We will not loosen the restriction, all type parameters in the extension block declaration must be inferrable from the extension parameter.

#### Accessibility

Question: https://github.com/dotnet/csharplang/blob/82157ff229f6c1bd2954a96ec2acb47064a48bad/proposals/extensions.md#accessibility

Finally today, we took a brief look at accessibility to get an initial gut feeling. The expressed sentiment in the room leaned towards
`private` being with respect to the entire static class, not towards an individual extension block, but we did not have time to deeply
dive into this topic, so no conclusions were made.
