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