Casting between classes with generics
.net, c#, generics
Solution
`SVM` is a subtype of `VMSBase<SpecialModel>`, so it can be converted to one.
But there's no polymorphic relationship between `VMSBase<SpecialModel>` and `VMSBase<Model>`, because the generic type parameter `T` in `VMSBase<T>` is invariant.
In order for `VMSBase<X>` to be a subtype of `VMSBase<Y>` (where `X` is a subtype of `Y`), `T` has to be covariant. You mark it as covariant using the `out` keyword: `VMSBase<out T>`. This, however, forces you to use the type `T` only for return values from all members (methods, properties, etc) and never as an input value (method arguments).
There's another catch: c# only allows variance on interfaces. So you'll have to change both VMBase and VMSBase to be interfaces.
class Program
{
static void Main(string[] args)
{
SVM a = new SVM();
var b = a as IVMSBase<Model>;
}
}
class SVM : IVMSBase<SpecialModel> {}
interface IVMSBase<out TS> : IVMBase<TS> where TS : Model {}
interface IVMBase<out T> where T : Model {}
More info: Covariance and Contravariance FAQ
Problem
Can someone please explain why this code snippet is not working? Why is a not castable to b? I was thinking about covariance and contravariance but as far as I'm concerted this is not applicable to abstract classes. Compile Error: Cannot convert type 'ConsoleApplication1.SVM' to 'ConsoleApplication1.VMSBase' ConsoleApplication1\Program.cs ``` class Program { static void Main(string[] args) { var a = new SVM(); var b = (VMSBase<Model>)a; } } class SVM : VMSBase<SpecialModel> { } class VMSBase<TS> : VMBase<TS> where TS : Model { } class VMBase<T> where T : Model { } class SpecialModel : Model { } class Model { } ```