Suppose I have three methods:
void Foo(MemoryStream v) {Console.WriteLine ("MemoryStream");}
void Foo(Stream v) {Console.WriteLine ("Stream");}
void Foo(object v) {Console.WriteLine ("object");}
I call method Foo
passing first parameter of open generic type:
void Bar<T>()
{
Foo(default(T)); //just to show the scenario
//default(T) or new T() doesn't make a difference, null is irrelevant here
}
I want to call MemoryStream
overload, so I close generic type of method Bar
with MemoryStream
:
Bar<MemoryStream>();
but the object
overload is called. If I add generic constraint to Foo signature where T : Stream
, then the Stream
version is called.
Is there a way to dispatch method call to MemoryStream
overload, based on open generic type T
?
I don't want to use Delegate.CreateDelegate
or other Reflection APIs. Just in the means of C# language. I'm probably missing something within the language itself.
Tried this scenario with value types as closed generic type and using static methods.
A generic method can also be overloaded by nongeneric methods. When the compiler encounters a method call, it searches for the method declaration that best matches the method name and the argument types specified in the call—an error occurs if two or more overloaded methods both could be considered best ...
Answer: Yes, we can overload a generic methods in C# as we overload a normal method in a class. Q- If we overload generic method in C# with specific data type which one would get called? Answer: Function with specific data type i.e int will be called.
The where clause in a generic definition specifies constraints on the types that are used as arguments for type parameters in a generic type, method, delegate, or local function. Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type.
What you describe is called "template specialization" and doesn't work in C#. It is available in C++ but still hasn't made its way to C#.
This has already been answered in "C# generic interface specialization". The short version is that you can't do it. You can work around it forcing runtime resolution but in this case using generics makes no sense. Generics should be used to use the same code on different types.
Perhaps there is another way of doing what you really want. I've run in similar situations when implementing the Strategy or Template Method patterns, where I want most of the code to work in the general case but modify some specific steps.
In such cases it's better to inject the custom steps to your class as interfaces, or even Func<> objects that specialize the behavior, when you actually create the "Template Method".
Of course, there are a lot of other ways to do this, some of which work better than others for specific problems
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With