Back to Csharplang

C# Language Design Meeting for February 26th, 2025

meetings/2025/LDM-2025-02-26.md

latest3.2 KB
Original Source

C# Language Design Meeting for February 26th, 2025

Agenda

Quote of the Day

  • "I tried to chase the pony... the lesson is that it's too hard." "I think that's the thing that scared me about this, we kept coming up with examples where the pony got hurt."

Discussion

Extensions

Champion issue: https://github.com/dotnet/csharplang/issues/8697
Specification: https://github.com/dotnet/csharplang/blob/688ef1e9d1646597f2be9dd56b674a06b0f20c13/proposals/extensions.md
Reviewed document: https://github.com/dotnet/csharplang/blob/688ef1e9d1646597f2be9dd56b674a06b0f20c13/meetings/working-groups/extensions/implicit-compatibility-for-ported-extension-methods.md

Last time, we asked the working group to go look at compatibility mechanisms for bridging old extension lookup and new extension lookup, and to come back with the implications of this. The working group has done so, and we are looking at the results of that investigation today. The first thing that we wanted to be clear about is that the potential breaks listed here aren't exhaustive: they're what we've found so far, some of them even as recently as the morning of the meeting. We do think that these breaks are likely to be edge cases in general, but we can't claim that for certain.

We ultimately need to decide on what form of semantics we want to go with for extension lookup. We see 4 different possible options:

  1. Use the 2-stage lookup process, and make no attempt to bridge semantics for compat.
  2. Use the 2-stage lookup process, and have an explicit opt-in for users to get compat.
  3. Use the 2-stage lookup process, and have an implicit fixup for compat.
  4. Use the 1-stage lookup process, which comes with built-in compat because it's the same lookup process as existing extensions.

We're particularly concerned about user experience in the future of C# here. We don't want to get to a world in 5 years where users need to understand the difference between old and new extensions, when to prefer the newer form over other, what overload resolution minutiae apply to either form, how to document the old form vs the new form, etc. We think any of the first two has that problem: authors will either need to know when to pick one or the other, or they will need to know when to opt-in to compat. Further, the users of libraries will need to know whether they are using the old or new extension form, which means figuring out a way to document this. Option 3 would be nice if we could figure it out, but we think we've sufficiently proven that this would be extremely difficult.

4 does mean that we abandon some niceties that we'd get with a new form. For example, it means that we couldn't let type parameters that come from the receiver of an extension method be inferred. However, we have a separate proposal (https://github.com/dotnet/csharplang/issues/8968) for allowing some type parameters to be dropped, and it would be more broadly applicable. Given all of this, we prefer option 4, and will proceed with having new instance extension methods use the same lookup algorithm that current instance extensions use.

Conclusion

Instance extension methods in extension blocks will use the same lookup mechanism as current extension methods do.