meetings/2025/LDM-2025-06-04.md
Champion issue: https://github.com/dotnet/csharplang/issues/8697
Specifications:
We spent today reviewing open questions in the extension space, starting first with extension operators specifically, then moving on to more general questions.
We started by thinking about whether we should allow nullable value type operators to be defined as extensions in an extension block for their underlying type. There are a few technical challenges in the specification and compiler to allowing this, and a clear workaround of simply defining the operators in an extension block on the actual nullable value type. Given that, we are fine with the proposed restriction for now, and can revisit at a later time if we get enough feedback on the restriction.
Restriction accepted: extension operators can only be declared for the type being extended in an extension block, not for the nullable underlying type.
An original principle of this rule is that & and && should call the same & operator, which this proposal would violate.
While there is some precedent for us allowing operators to change between similar operations (the new += overloads vs +,
for example), we don't think we have the use cases to justify this change at this point.
We're not doing anything here for now. Rejected until we see use cases.
We don't have any additional comments on this proposal. It seems logical and straightforward, and is accepted.
Proposal accepted.
There is definitely value in allowing anything to work here, despite the potential for footguns, but we think there will be more design work needed that we do not currently have the bandwidth to do. Therefore, at least for now, the restriction is adopted.
Restriction adopted, we can look at it again in the future when there is more bandwidth.
First up in extensions proper, we took a quick look at the proposed rules for delegate-returning properties. We have no issues with the proposed rules, and adopt them as written.
Rules adopted as written.
Next up, we looked at one of the more controversial restrictions of the current proposal, that only type parameters that are directly used in the extension parameter are allowed on the extension block itself. This ends up being a blocker for several scenarios in both the BCL and our early adopters. Given this, we want to lift the restriction, but the question then becomes "to what extent". The restriction does provide some useful guardrails, particularly for non-methods members that do not have a location to provide type parameters. We don't think there's any harm in fully lifting the restrictions on actual methods, but for non-methods, we think we need to keep a form of the restriction: the type parameters must be used within all parameters of the member.
Restriction is loosened to "No restriction on extension methods. Other extension members must use all type parameters in their parameter types."
Finally today, we looked at the proposed cref syntax for referencing extensions. There's a wrinkle in this of which member a
cref actually references: the implementation, or the skeleton facade. Both will have different IDs in the actual documentation
file. However, this is a question in itself: should C# normalize this so users don't need to understand the difference between
the two? There's a good argument for doing this, but we then need to decide which thing to normalize to. Another question that
came up is whether there should be an entirely bespoke syntax here, or if users can just refer to things in extension or
disambiguation form directly, ie as <see cref="int.M()" /> or <see cref="E.M(int)" />. This form would encourage thinking
of the implementation vs skeleton separately, which could be a problem, but is also more straightforward without needing to
introduce new formats. A further item to consider is whether we want to allow linking directly to an extension block in
a doc comment.
We did not come to a decision here today, and will need to come back next week on it.