Interface with generic parameter vs Interface with generic methods

前端 未结 4 1139
别那么骄傲
别那么骄傲 2020-12-08 02:34

Let\'s say I have such interface and concrete implementation

public interface IMyInterface
{
    T My();
}

public class MyConcrete : IMyInterface&l         


        
相关标签:
4条回答
  • 2020-12-08 02:50

    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 named My 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 call My with a string.

    0 讨论(0)
  • 2020-12-08 02:56

    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

    public T My<T>()
    {
        throw new NotImplementedException();
    }
    

    and when you call the method you can use the string there.

    0 讨论(0)
  • 2020-12-08 03:02

    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?
    }
    
    0 讨论(0)
  • 2020-12-08 03:03

    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();
        }
    }
    
    0 讨论(0)
提交回复
热议问题