Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interface with generic parameter vs Interface with generic methods

Tags:

c#

.net

clr

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>()?

like image 765
Jevgenij Nekrasov Avatar asked Jul 11 '13 14:07

Jevgenij Nekrasov


People also ask

What is the difference between a generic class and a generic method?

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.

When would you use a generic interface?

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.

What is the use of generic interface in C#?

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.

What is a generic interface?

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.


2 Answers

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? } 
like image 116
MarcinJuraszek Avatar answered Sep 30 '22 13:09

MarcinJuraszek


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();     } } 
like image 31
Christoffer Mansfield Avatar answered Sep 30 '22 11:09

Christoffer Mansfield