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>()
?
A generic class or structure can contain nongeneric procedures, and a nongeneric class, structure, or module can contain generic procedures. A generic procedure can use its type parameters in its normal parameter list, in its return type if it has one, and in its procedure code.
It's often useful to define interfaces either for generic collection classes, or for the generic classes that represent items in the collection. To avoid boxing and unboxing operations on value types, it's better to use generic interfaces, such as IComparable<T>, on generic classes.
A generic interface is primarily a normal interface like any other. It can be used to declare a variable but assigned the appropriate class. It can be returned from a method. It can be passed as argument.
Generic Interfaces in Java are the interfaces that deal with abstract data types. Interface help in the independent manipulation of java collections from representation details. They are used to achieving multiple inheritance in java forming hierarchies. They differ from the java class.
Your generic method implementation has to be generic as well, so it has to be:
public class MyConcrete2 : IMyInterface2 { public T My<T>() { throw new NotImplementedException(); } }
Why you can't do My<string>()
here? Because interface contract needs a method, that could be called with any type parameter T
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:
public interface IMyInterface2 { T My<T>(T value); } public class MyClass21 : IMyInterface2 { public string My<string>(string value) { return value; } } public class MyClass22 : IMyInterface2 { public int My<int>(int value) { return value; } }
Usage:
var item1 = new MyClass21(); var item2 = new MyClass22(); // they both implement IMyInterface2, so we can put them into list var list = new List<IMyInterface2>(); list.Add(item1); list.Add(item2); // iterate the list and call My method foreach(IMyInterface2 item in list) { // item is IMyInterface2, so we have My<T>() method. Choose T to be int and call with value 2: item.My<int>(2); // how would it work with item1, which has My<string> implemented? }
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:
public interface IMyInterface2<T> { T My(); } public class MyConcrete2 : IMyInterface2<string> { public string My() { throw new NotImplementedException(); } }
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