有人可以解释为什么这段代码不起作用?b为什么不能施放?我在考虑协方差和逆变,但就我而言,这不适用于抽象类.
编译错误:无法将类型"ConsoleApplication1.SVM"转换为"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
{
}
Run Code Online (Sandbox Code Playgroud)
SVM是一个子类型VMSBase<SpecialModel>,因此它可以转换为一个.
但有之间没有多态性关系VMSBase<SpecialModel>和VMSBase<Model>,因为泛型类型参数T中VMSBase<T>是不变的.
为了VMSBase<X>成为VMSBase<Y>(其中X是子类型Y)的子类型,T必须是协变的.您使用out关键字将其标记为协变:VMSBase<out T>.但是,这会强制您T 仅将类型用于所有成员(方法,属性等)的返回值,而不是作为输入值(方法参数).
还有一个问题:c#只允许接口出现差异.因此,您必须将VMBase和VMSBase都更改为接口.
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 {}
Run Code Online (Sandbox Code Playgroud)
更多信息:协方差和逆变法常见问题解答