Back to Csharplang

C# Language Design Meeting for June 23rd, 2025

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

latest5.3 KB
Original Source

C# Language Design Meeting for June 23rd, 2025

Agenda

Quote of the Day

  • "So we pick the method" "But the spec says that should have been an ambiguity"
  • "That can't be it, we have 20-odd minutes left in the meeting. That's illegal!"

Discussion

Extensions

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

Use of extension operators in LINQ expression trees

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

Previously, we'd decided to use the existing Expression factory methods for expression trees. This works in most cases, but falls over in scenarios that need multiple extension operators, such as && or ||. For these scenarios, the ideal fix would be to add a new factory method, but we don't think this is something that we can do at this time. Therefore, we'll simply note the issue in documentation, and if we make future changes to expression trees, we could potentially address this shortcoming then.

Conclusion

Proposed rules approved. && and || implemented via extensions will not be allowed in expression trees.

ref encoding and conflict checks

Question: https://github.com/dotnet/csharplang/blob/d9aac41d8b0ff4d2bb322ffb8f85a4a4a14690df/proposals/extensions.md#metadata

Confirm that ref should not be included in extension type name

After some discussion here, we realized that the question has some fundamental issues that need to go back to the working group. https://github.com/dotnet/roslyn/issues/79043 demonstrates an issue with our current conflict checking rules; because we do not consider refness when doing signature conflict checking, we prevent this scenario from migrating to new extensions. We also don't think this is particularly edge case code; it's certainly not mainstream, but it's not a truly niche thing. The proposed rules for ref name encoding would be at odds with allowing this code to be valid C#; while that particular scenario would be okay because the constraints would force the creation of two different skeleton containers, the constraints are not the important bit that allows the code to be valid. What allows the code to be valid is the refness, and it would be odd to have a form that is allowed in C# but we can't actually emit in many cases. Given this, the working group will take another look at the conflict rules and bring back a new proposal for how to encode these bits.

Extern support

Question: https://github.com/dotnet/csharplang/blob/d9aac41d8b0ff4d2bb322ffb8f85a4a4a14690df/proposals/extensions.md#extern

We confirmed support here. Existing extensions support extern, so the new ones will too.

Lookup

Question: https://github.com/dotnet/csharplang/blob/d9aac41d8b0ff4d2bb322ffb8f85a4a4a14690df/proposals/extensions.md#lookup

Question 1

Confirm that we want betterness rules to apply even when the receiver is a type

Next, we looked at the proposed static member betterness rules. The existing rules are based on the model that there is an implicit parameter here, the type itself, and that therefore everything that goes into standard parameter checking should go into betterness for static invocations. We don't feel that this is a convincing argument, as there is no value to applying refness to here. Further, it would mean that users would need to understand that it would be a source-breaking change to move an extension from an extension(in int) block to an extension(int) block, because it could affect the tiebreaking with another library's extensions. We therefore conclude that static extension lookup will only look at the type being extended when doing resolution, not any other tiebreaking criteria.

Conclusion

For static extension members, we will only use the type for the extra "parameter".

Question 2

Confirm that we don't want some betterness across all members before we determine the winning member kind

We're concerned here that if we don't support some form of betterness, it will block users from being able to move things that are currently written as extension methods but would be better written as extension properties. These APIs are expressed as well as they can be today, given that we don't have extension properties today. We feel strongly that these APIs should be able to work, but we are also uncertain as to whether we can reasonably deliver this experience before C# 14 releases. The status quo does protect our ability to design rules that by and large do the "right" thing by default, invoking methods where appropriate and calling properties when appropriate. We'll therefore proceed with this, and work on a design for making this "just work".

Conclusion

Ambiguity rules will be left in place while we work on creating rules for making code work as the user would expect.