一篇文章看懂C#中的协变、逆变
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)官方对 协变、逆变 的定义现在是否能看懂?
上面看懂了,官方定义肯定也是没问题的。派生程度小可以理解为基类,派生程度大可以理解为子类或派生类,至于为什么用程度这个词,是因为继承链的深度是没限制的。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。
您可能感兴趣的文章
- 01-10winform 实现控制输入法
- 01-10C#编程自学之类和对象
- 01-10C#中深度复制和浅度复制详解
- 01-10C#编程自学之流程控制语句
- 01-10C#影院售票系统毕业设计(3)
- 01-10C#影院售票系统毕业设计(4)
- 01-10C#实现带消息数的App图标
- 01-10C#如何实现图片查看器
- 01-10谈C# using的用法与好处
- 01-10C# 后台处理图片的几种方法
阅读排行
本栏相关
- 01-10C#通过反射获取当前工程中所有窗体并
- 01-10关于ASP网页无法打开的解决方案
- 01-10WinForm限制窗体不能移到屏幕外的方法
- 01-10WinForm绘制圆角的方法
- 01-10C#实现txt定位指定行完整实例
- 01-10WinForm实现仿视频播放器左下角滚动新
- 01-10C#停止线程的方法
- 01-10C#实现清空回收站的方法
- 01-10C#通过重写Panel改变边框颜色与宽度的
- 01-10C#实现读取注册表监控当前操作系统已
随机阅读
- 01-10C#中split用法实例总结
- 08-05织梦dedecms什么时候用栏目交叉功能?
- 01-10delphi制作wav文件的方法
- 08-05DEDE织梦data目录下的sessions文件夹有什
- 01-10SublimeText编译C开发环境设置
- 04-02jquery与jsp,用jquery
- 01-10使用C语言求解扑克牌的顺子及n个骰子
- 01-11ajax实现页面的局部加载
- 08-05dedecms(织梦)副栏目数量限制代码修改
- 01-11Mac OSX 打开原生自带读写NTFS功能(图文