Let's say I have such interface and concrete implementation
public interface IMyInterface<T>
{
T My();
}
public class MyConcrete : IMyInterface<string>
{
public string My()
{
return string.Empty;
}
}
So I create MyConcrete implementation for strings
, I can have one more concrete implementation for int
. And that's ok. But let's say, that I want to do the same thing, but with generic methods, so I have
public interface IMyInterface2
{
T My<T>();
}
public class MyConcrete2 : IMyInterface2
{
public string My<string>()
{
throw new NotImplementedException();
}
}
So I have the same IMyInterface2
, but which defines generic behavior by means of T My<T>()
. In my concrete class I want to implement My
behavior, but for concrete data type - string
. But C# doesn't allow me to do that.
My question is why I cannot do that?
In other words, if i can create concrete implementation of MyInterface<T>
as MyClass : MyInterface<string>
and stop genericness at this point, why I can't do that with generic method - T My<T>()
?
Your generic method implementation has to be generic as well, so it has to be:
Why you can't do
My<string>()
here? Because interface contract needs a method, that could be called with any type parameterT
and you have to fulfill that contract.Why you can't stop genericness in this point? Because it would cause situations like following:
Class declarations:
Usage:
Your solution does not work for two reasons.
First, an interface is a contract. When you implement
IMyInterface2
you guarantee that you will implement a function namedMy
that takes a generic type parameter and returns that type.MyConcrete2
does not do this.Second, C# generics do not allow any kind of type parameter specialization. (I do wish C# supported this.) This is a common thing in C++ templates where your example would compile, but any usages of
MyConcrete2
would fail to compile if they don't callMy
with astring
.when you write the Generic Method the Definition is for keeping the placeholder. Actual Type comes into picture when you call the method. so instead you should write
and when you call the method you can use the string there.
Because your interface declares a generic method
T My<T>()
, but you implementation does not implement a function with that specific signature.To achieve what you want, you need to provide the T generic parameter to the interface instead, in your first example: