使用泛型在类之间进行转换

 耿耿于怀r 发布于 2023-01-30 10:31

有人可以解释为什么这段代码不起作用?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,因此它可以转换为一个.

但有之间没有多态性关系VMSBaseVMSBase,因为泛型类型参数TVMSBase不变的.


为了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 {}

更多信息:协方差和逆变法常见问题解答

1 个回答
  • SVM是一个子类型VMSBase<SpecialModel>,因此它可以转换为一个.

    但有之间没有多态性关系VMSBase<SpecialModel>VMSBase<Model>,因为泛型类型参数TVMSBase<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 {}
    

    更多信息:协方差和逆变法常见问题解答

    2023-01-30 10:33 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有