C# casting an inherited Generic interface

后端 未结 2 1343
既然无缘
既然无缘 2020-12-06 01:18

I\'m having some trouble getting my head around casting an interface I\'ve come up with. It\'s an MVP design for C# Windows Forms. I have an IView class which I implement o

相关标签:
2条回答
  • 2020-12-06 01:46

    The problem is the generic type parameter. If you make the interface parameter covariant then the cast will work.

    This is accomplished by adding the out keyword, like so:

    interface IPresenter<out V> where V : IView
    {
        void PresBlah();
    
    }
    

    You can learn more about how this works with the following MSDN article: Covariance and Contravariance in Generics. The section Generic Interfaces with Covariant Type Parameters specifically applies to your question.

    Update: Make sure you check the comments between @phoog and me. If your actual code accepts a V as an input, you will be unable to make it covariant. The referenced article and @phoog's answer explains this case in further detail.

    0 讨论(0)
  • 2020-12-06 01:51

    CPresenter<CView> is not an IPresenter<IView>, just as List<int[]> is not an IList<IEnumerable>.

    Think about it. If you could get an IList<IEnumerable> reference to a List<int>, you could add a string[] to it, which would have to throw an exception. The whole point of static type checking is to prevent the compilation of such code.

    If the interface allows, you could declare the type parameter as covariant (IPresenter<out V> where V : .... Then the interface would behave more like IEnumerable<out T>. This is only possible if the type parameter is never used in an input position.

    To go back to the List<int[]> example, it is safe to treat it as an IEnumerable<IEnumerable>, because you can't add anything to an IEnumerable<T> reference; you can only read things out of it, and, in turn, it is safe to treat an int[] as an IEnumerable, so all is well.

    0 讨论(0)
提交回复
热议问题