一篇文章看懂C#中的协变、逆变

所属分类: 软件编程 / C#教程 阅读数: 146
收藏 0 赞 0 分享

1. 基本概念

官方:协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型。[MSDN]

公式:

          协变:IFoo<父类> = IFoo<子类>;

          逆变:IBar<子类> =  IBar<父类>;

暂时不理解没关系,您接着往下看。

2. 协变(Covariance)

1) out关键字

     对于泛型类型参数,out 关键字可指定类型参数是协变的。 可以在泛型接口和委托中使用 out 关键字。[MSDN]

2) 鲁迅:一张图胜过千言万语(图小看不清,单机鼠标右键 -> 在新标签页中打开图片)

   

           备注:泛型委托的协变原理也是一样的。

        3) 什么是协变?

           协变就是对具体成员的输出参数进行一次类型转换,且类型转换的准则是 “里氏替换原则”。

3. 逆变(Contravariance)

 1) in关键字

     对于泛型类型参数,in 关键字可指定类型参数是逆变的。 可以在泛型接口和委托中使用 in 关键字。[MSDN]

 2) 鲁迅:一张图胜过千言万语(图小看不清,单机鼠标右键 -> 在新标签页中打开图片)

     

    备注:泛型委托的逆变原理也是一样的。

        3) 什么是逆变?

            逆变就是对具体成员的输入参数进行一次类型转换,且类型转换的准则是 “里氏替换原则”。

4. 自问自答

1)协变、逆变 为什么只能针对泛型接口或者委托?而不能针对泛型类?

      因为它们都只能定义方法成员(接口不能定义字段),而方法成员在创建对象的时候是不涉及到对象内存分配的,所以它们是类型(内存)安全的。

      为什么不针对泛型?因为泛型类是模板类,而类成员是包含字段的,不同类型的字段是影响对象内存分配的,没有派生关系的类型它们是不兼容的,也是内存不安全的。

2)协变、逆变 为什么是类型安全的?

      本质上是里氏替换原则,由里氏替换原则可知:派生程度小的是派生程度大的子集,所以子类替换父类的位置整个程序功能都不会发生改变。

3)官方对 协变、逆变 的定义现在是否能看懂?

      上面看懂了,官方定义肯定也是没问题的。派生程度小可以理解为基类,派生程度大可以理解为子类或派生类,至于为什么用程度这个词,是因为继承链的深度是没限制的。

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。

更多精彩内容其他人还在看

C# 大小写转换(金额)实例代码

C# 大小写转换(金额)实例代码,需要的朋友可以参考一下
收藏 0 赞 0 分享

C# WinForm中Panel实现用鼠标操作滚动条的实例方法

由于在WinForm中Panel不能直接响应鼠标的滚动事件,只好采用捕获窗体的滚动事件。
收藏 0 赞 0 分享

C#访问应用程序配置文件的方法

C#访问应用程序配置文件的方法,需要的朋友可以参考一下
收藏 0 赞 0 分享

C#读写文件的方法汇总

C#读写文件的方法汇总,需要的朋友可以参考一下
收藏 0 赞 0 分享

C#计算代码执行时间的方法

在一些测试工作时我们需要获得高精度的代码执行时间以比较其效率。
收藏 0 赞 0 分享

C# 动画窗体(AnimateWindow)的小例子

C# 动画窗体(AnimateWindow)的小例子,需要的朋友可以参考一下
收藏 0 赞 0 分享

C# zxing二维码写入的实例代码

C# zxing二维码写入的实例代码,需要的朋友可以参考一下
收藏 0 赞 0 分享

c#判断输入的是不是数字的小例子

c#判断输入的是不是数字的小例子,需要的朋友可以参考一下
收藏 0 赞 0 分享

c# 深拷贝与浅拷贝的区别分析及实例

浅拷贝(影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用. 深拷贝(深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.就是说完全是新对象产生的.
收藏 0 赞 0 分享

C#利用com操作excel释放进程的解决方法

最近利用Microsoft.Office.Interop.Excel.Application读取一个excel后,进程中一直存在excel,在网上找了一阵子,其中有几个解决方案
收藏 0 赞 0 分享
查看更多