Proposal: allow generic constraints to be part of the signature for overloading resolution #2013
Replies: 10 comments 6 replies
-
The CLR doesn't consider generic type constraints to be a part of the method signature thus you can't have two overloads that only differ by those constraints. There's nothing much that C# can do here without CLR changes. As for this explicit overload resolution, if the overloads are that convoluted I'd suggest using method names to disambiguate them. That would already be substantially less verbose than what you've proposed here. |
Beta Was this translation helpful? Give feedback.
-
Ok, then I hope that those in charge of the CLR consider including them as part of method signature.
Not necessarily since you could disambiguate them with something as simple as ...: myField.{className}.MyTestMethod(...); ... and yet still feeling that you are using an (extension) method. |
Beta Was this translation helpful? Give feedback.
-
Should this be listed in #317 ? |
Beta Was this translation helpful? Give feedback.
-
I'd wager that the benefit of such overloading wouldn't benefit the cost of modifying the CLR. This limitation has existed for the last 13 years and is at worst a minor impediment. It's not like all methods need to have the same name. I also think that it would be a breaking change to the IL language where all method calls are required to express the full signature of the target method. I don't know that anyone cares to maintain backward/forward compatibility in the IL language itself, but I don't think that the CLR could be amended without additional work on the IL assemblers themselves. |
Beta Was this translation helpful? Give feedback.
-
#317 What language proposals would benefit from CLR changes? Added there for consideration. |
Beta Was this translation helpful? Give feedback.
-
This solution would help me a lot I will give the most current example that I stumbled upon it public abstract class BasicBusiness<T, TKey> where T : class, new()
{
public async virtual Task<T> Get(TKey key) { /*...*/ }
public async virtual Task<T> Remove(TKey key) { /*...*/ }
/* etc */
}
public abstract class BasicBusiness<T> : BasicBusiness<T, int> where T : EntityIntKey, new()
{
}
public abstract class BasicBusiness<T> : BasicBusiness<T, short> where T : EntityShortKey, new()
{
}
public abstract class BasicBusiness<T> : BasicBusiness<T, Guid> where T : EntityGuidKey, new()
{
} This would have avoided me major refactoring efforts |
Beta Was this translation helpful? Give feedback.
-
You could add to signature only information about reference or value type. Of course, this would not bring much benefit, but it would be useful sometimes. And for |
Beta Was this translation helpful? Give feedback.
-
I'd like to know whether this proposal has been considered in #317 |
Beta Was this translation helpful? Give feedback.
-
Was it listed in #317 ? |
Beta Was this translation helpful? Give feedback.
-
I also wondered if it could be technically possible to add the generic parameters as part of a method signature. The reason is that regardless of how stupid the following example is, I find the following compiler behaviour inconsistent if I didn't know that the generic parameter doesn't make a signature unique. The first case compiles fine, while the second case generates an error as the method can be ambiguous, however, technically they both mean the same thing. Generic methods can and should be more powerful than they are now for generic type specialization and this feature could help it. Not completely related, but interesting to highlight, the following won't be instead considered ambiguous
because there is a c# rule that says that methods with optional parameters are considered "better" |
Beta Was this translation helpful? Give feedback.
-
Currently, it is not allowed to declare the following methods on the same class:
Although you are clearing stating that one method should receive reference types and the other one value types, you get the following compiling error:
Error CS0111 Type 'MyTestClass1' already defines a member called 'MyTestMethod1' with the same parameter types
.As stated in #1628, a workaround is simple with C# 7.3: to split those methods in different classes.
Now, what would happen if instead you declare the following methods ...?
... and then you attempt to split those methods in different classes? You will get the following error:
The call is ambiguous between the following methods or properties ...
. The solution: to enclose each class in its own namespace, which then leads me to the following issue: what would happen if somewhere in your code you reference both namespaces at top-most level? You will be getting again the same error due to ambiguity. Ditto, for the case when you find two generic methods with the same name, signature and constraints in different classes/namespaces. Of course, that this situation can be solved when you declare all classes and methods your-self, but when you consume many APIs from third-parties, workarounds can be found but at the expense of simplicity.So my proposal here is two-folded:
To include generic constraints as part of the signature to (a) allow defining generic overloads on the same class/struct, and (b) improve conflict resolution, so that the most specific method is chosen by the compiler by default (in case of the last example above, when working with an enum, the second
MyTestMethod2
will be picked by the compiler because the constraint requests an struct which is also and Enum). And,To allow a way to easily select which method to use when the compiler cannot automatically resolve the conflict. For example, with an approach like the following ...:
... and so on so forth.
Beta Was this translation helpful? Give feedback.
All reactions