温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

C#中的协变与逆变怎么实现

发布时间:2022-02-07 09:56:18 来源:亿速云 阅读:139 作者:iii 栏目:开发技术

本篇内容介绍了“C#中的协变与逆变怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

前言

在C#编程中,由于存在类型之间的强制转换,很容易会出现所谓的类型可变性说法,存在协变、逆变、不变三种。

就比如前一篇文章介绍的泛型概念,如果创建了泛型类型的实例,编译器会接受泛型类型声明以及类型参数来创建构造类型。但是在日常使用过程中,我们可能会将派生类型分配给基类型的变量,有时候会出现错误。

这里就存在一个赋值兼容性问题。

每一个变量都有一种类型,可以将派生类对象的实例赋值给基类变量(好比之前子类声明的变量可以赋值给父类声明的变量一样)。

如下所示:

        class People
        {
            public int Age = 27;
        }
 
        class AhuiPeople : People
        {
 
        }
            People ahui = new People();
            People people = new AhuiPeople();
 
            Console.WriteLine("Age:"+people.Age);
            Console.ReadKey();

C#中的协变与逆变怎么实现

协变和逆变

我们按照同样的逻辑,在泛型委托中进行这种强类型的转换,会发现即使基类和派生类之间可以进行正常的转换,但是委托之间不能进行转换会出现异常错误提示。

具体如下代码所示:

        delegate T AgeDelegate<T>();         
 
        static AhuiPeople GetAge()
        {
            return new AhuiPeople();
        }

在转换过程中,委托的具体用法,但是这样子编译器提示错误。

            AgeDelegate<AhuiPeople> ahui = GetAge;
            AgeDelegate<People> people = ahui;

错误提示

C#中的协变与逆变怎么实现

这就是上面解释的那样子,基类和派生类之间可以进行转换但是委托之间未存在关联,无法进行强制类型的转换。
那么想解决这个问题就引入了协变来解决。

如果派生类只是用于输出值,那么这种结构化的委托有效性之间的常数关系叫做协变,可通过主动告知编译器我们的期望,使用Out关键字标记委托声明中的类型参数。

        delegate T AgeDelegate<out T>();

修改成这样子后,上面错误演示的代码编译器就可以正常编译通过了。

C#中的协变与逆变怎么实现

上面简单介绍了协变,那么接下来我们来看逆变是什么。

其实逆变就是在委托中既要声明委托类型,也要在委托方法中有实参。

这种在期望传入基类时允许传入派生对象的特性叫做逆变。 逆变使用关键字in来标记。

具体如下代码所示:

        delegate void AgeDelegate<in T>(T p); 
        static void GetAge(People p)
        {
            Console.WriteLine(p.Age);
        }
            AgeDelegate<People> ahui = GetAge;
            AgeDelegate<AhuiPeople> people = ahui;
 
            people(new AhuiPeople());
            Console.WriteLine();
            Console.ReadKey();

输出结果

C#中的协变与逆变怎么实现

既然协变和逆变可以使用在委托上,那么接口上也可以使用,此时也需要使用out和in关键字。

“C#中的协变与逆变怎么实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI