Back to Csharplang

C# Language Design Meeting for June 11th, 2025

meetings/2025/LDM-2025-06-11.md

latest7.3 KB
Original Source

C# Language Design Meeting for June 11th, 2025

Agenda

Quote of the Day

Nothing particularly amusing was said today, sorry.

Discussion

Extensions

Champion issue: https://github.com/dotnet/csharplang/issues/8697
Specifications:

Dynamic resolution of operator true/false

Question: https://github.com/dotnet/csharplang/blob/fdc35c9c2c2ff4fd532c9733a9ade5f89d37018e/proposals/extension-operators.md#dynamic-evaluation

We think the proposed restriction makes sense. The C# spec says that when one or both operands of a binary operator is dynamic, the entire operation, including lookup of operator true/false, occurs at runtime. The compiler performing the lookup at compile-time for operator true/false for the non-dynamic operand is an optimization, nothing more, and the dynamic binder would not be able to find extension true/false operators, just as it can't find instance extension methods today.

Conclusion

Restriction accepted. Extension operator true/false are not used for dynamic && or ||.

Extension operators in LINQ expression trees

Question: https://github.com/dotnet/csharplang/blob/fdc35c9c2c2ff4fd532c9733a9ade5f89d37018e/proposals/extension-operators.md#use-of-extension-operators-in-linq-expression-trees

The proposal was accepted without further discussion beyond what is in the question itself.

Conclusion

Accepted.

Built-in operator protection rules

Specification: https://github.com/dotnet/csharplang/blob/fdc35c9c2c2ff4fd532c9733a9ade5f89d37018e/proposals/extension-operators.md#is-the-rule-an-extension-operator-may-not-have-the-same-signature-as-a-predefined-operator-worth-having-as-specified

Further testing of our proposed rules for protecting built-in operators has revealed holes in our proposal, namely when conversions to built-in types are involved, bypassing the existing rule. While we could create a more complicated rule to address this, involving overload resolution, we don't like the end result: it's a complicated rule that we don't feel carries sufficient weight to justify the complexity. We could reduce this to a warning instead, and conceptually don't have an issue with it, but we don't think that such a warning must be present; we think that when a predefined operator is chosen over an extension operator, it will be fairly obvious what is happening.

Conclusion

Rule is abandoned. We will not have built-in errors or warnings here.

Extension module initializers

Question: https://github.com/dotnet/csharplang/blob/fdc35c9c2c2ff4fd532c9733a9ade5f89d37018e/proposals/extensions.md#open-issues

The question here is whether to permit extension implementation members to be module initializers. We don't have any motivating scenarios here and don't have a proposal for how the attribute would be applied to either skeleton or implementation members. Therefore, we will reject this until we have motivation to implement it.

Conclusion

Rejected.

Extension methods as entry points

Question: https://github.com/dotnet/csharplang/blob/fdc35c9c2c2ff4fd532c9733a9ade5f89d37018e/proposals/extensions.md#open-issues

We must keep the implementation methods for instance extension methods as entry point candidates, as it works today and we have a strong back-compat goal here. Therefore, we intend to continue permitting methods that end up having an implementation method with a valid entry point signature to be considered in the set of possible entry points.

Conclusion

Implementation methods that have a valid signature will be considered among the possible entry point candidates.

Langversion behavior for new extensions

Question: https://github.com/dotnet/csharplang/blob/fdc35c9c2c2ff4fd532c9733a9ade5f89d37018e/proposals/extensions.md#open-issues

After some consideration, we don't think we need to have lookup consider language version for the actual lookup process itself. The scenarios in which a user could run into issues are:

  • A delegate-returning property gets ahead of an old-style extension method, so obj.M() becomes an invocation of the delegate returned from the property M.
  • A method group used as an assignment/argument gets superseded by an extension property, so M(e.MethodGroup) goes from a method to a property.

In either of these cases, we will issue a LangVersion diagnostic but won't otherwise complicate lookup with exceptions around excluding new-style extensions. The main concern is that we can't issue a diagnostic for instance extension methods, since you can already have them today and going from old to new style is not otherwise a breaking change.

Conclusion

We will issue LangVersion diagnostics on successful lookups/overload resolutions that pick a non-instance extension method.

nameof

Question: https://github.com/dotnet/csharplang/blob/fdc35c9c2c2ff4fd532c9733a9ade5f89d37018e/proposals/extensions.md#nameof

Finally today, we took a look at nameof rules. There's a bit of tension here: we want to allow referencing an extension property in a nameof, but we want to be consistent with current rules around extension-based lookup in nameof. Today, extension methods cannot be referenced in nameof off their extended type or an instance of their extended type. They must be looked up on the extension container. This restriction was mostly about cutting design time to get extension methods shipped, and we're mixed on whether to keep it long term. We don't think that this is the entire solution though, as ambiguity once again raises its head. We came up with 3 main approaches to the lookup:

  1. ExtensionContainer.extension(param).Member - Essentially borrow the cref syntax. We think this is too heavy-handed for just nameof and want to avoid it.
  2. ExtendedType.Member - Allow this form and likely lift the restriction on all extension members. Do nothing to provide disambiguation syntax.
  3. ExtensionContainer.Member - Simply make this lookup work, even for extension properties and events.

We think we want option 3; it's the most consistent with the current approach and ensures that there isn't multiple ways to reference the member. At the same time, though, we know that we likely will not have time to design and implement this lookup for C# 14; after design, we may even decide that we don't like how the rules turn out and need to go back to the drawing board. Given this, we've decided that we will likely not support nameof on extension properties for C# 14. We will revisit and take up the design pen again as soon as we can here, but do not want to jeopardize shipping the feature over nameof support.