Closed Juulsn closed 1 month ago
Tagging subscribers to this area: @dotnet/area-system-reflection See info in area-owners.md if you want to be subscribed.
This is new C# language feature proposal. New C# language feature proposals should be opened in csharplang repo. I am going to transfer it there.
@jkotas Ups, sorry!
Background and motivation
I am using generics a lot and I'm a huge fan of the builder pattern. But one of the most frustrating things about generics and fluent APIs is, that you need to reserve a generic type for the return type.
In fluent APIs, especially those involving builders or chainable methods, it is common to work with generic extension methods. However, when multiple generic type parameters are involved, developers are often required to explicitly specify the same type multiple times, leading to verbose and repetitive code. This can reduce readability and increase the chance of errors in complex APIs. While workarounds like helper classes or verbose method signatures exist, they introduce unnecessary boilerplate. A solution to allow the return type of extension methods to automatically match the type of the calling instance, simplifying method signatures, improving type inference, and enhancing developer experience in fluent APIs is therefore needed.
This is why I'm proposing a new way to specify the return type in Extension Methods.
Currently, creating extension methods in C# for builders and fluent APIs can require verbose syntax, especially when working with generics. While it is possible to achieve the desired behavior with existing language features, the code can become unnecessarily cluttered when dealing with:
Helper
classes or explicitly specifying multiple type arguments).Here are three current approaches, each with their respective downsides:
Approach 0a: Basic Extension Method (No Generics)
TSelf
.Approach 0b: Basic Extension Method (return the base type)
Approach 1: Explicit Type Arguments
TSomeType
).Approach 2: Boilerplate with Helper Classes
Usage:
API Proposal
Proposal: The
same
KeywordTo simplify and enhance the readability of generic extension methods, I propose introducing a new
same
keyword. Thesame
keyword would refer to the calling object’s type (the type ofthis
), eliminating the need to specify type arguments explicitly or introduce boilerplate code.Example of Proposed Syntax:
same
represents the type of the calling object (builder
), making the method more concise and easier to understand.TSomeType
remains a generic type that must be specified, but the type of the calling object (same
) is inferred automatically.Extension Methods without the need of another generic argument - except the input type - might also benefit from the simpler syntax.
API Usage
Usage Example:
Advantages:
TypeHelper
classes.Alternative Designs
There are multiple alternatives to this proposal.
This might look like the following.
or
Risks
As far as I understand, this feature could be implemented as syntactic sugar, since there is an alternative way of doing this, with some boilerplate code.
The introduction of
same
would have minimal or no breaking changes at all, as it would represent a new keyword that’s only applicable in the context of extension methods. Existing code should not be affected unlesssame
is already used as an identifier for a generic type in an extension method, in which case renaming the generic type would resolve conflicts. An alternativ could be, that a generic type with the namesame
has a higher priority than the proposed keyword.Introducing another new keyword may complicate the language and make it harder to learn it. The
same
keyword primarily benefits scenarios where extension methods and fluent interfaces are used. It may not provide much utility beyond this specific use case. However, the keyword might be used in