Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics, Inheritance, and Casting

My question has to do with casting classes inside a generic type. While I realize that casting objects like List<string> to List<object> requires support for covariance to prevent adding object objects to a list that contains strings, I am wondering why a cast like below is not accepted by the compiler and whether it is solvable employing interfaces and co- or contravariance:

public class TypeA<T> {}

public class TypeB<T> {}

public class TypeC : TypeB<int> {}

class Program
{
    public static void MyMethod<OutputType>(TypeA<TypeB<OutputType>> Parameter) {}

    static void Main(string[] args)
    {
        TypeA<TypeC> Test = new TypeA<TypeC>();
        MyMethod<int>(Test);
    }
}

Compiling this results in an error:

Argument 1: cannot convert from 'ConsoleApplication1.TypeA<ConsoleApplication1.TypeC>' to 'ConsoleApplication1.TypeA<ConsoleApplication1.TypeB<int>>'.

even though TypeC is a direct descendent of TypeB<int>

like image 635
Mark A. Avatar asked Dec 29 '22 14:12

Mark A.


1 Answers

As other commenters have pointed out, despite the fact that TypeC is derived from TypeB<int>, it is not true that TypeA<TypeC> derives from TypeA<TypeB<int>>. However, you can probably get your code to work by adding an additional type parameter to MyMethod:

public static void MyMethod<DerivedB,OutputType>(TypeA<DerivedB> Parameter)
    where DerivedB : TypeB<OutputType> {}
like image 179
kvb Avatar answered Jan 11 '23 01:01

kvb