首页 / C# / c# 泛型协变逆变学习
c# 泛型协变逆变学习
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# 泛型协变逆变学习,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2251字,纯文字阅读大概需要4分钟。
内容图文
![c# 泛型协变逆变学习](/upload/InfoBanner/zyjiaocheng/848/2cb3fb1bfc974afb95ae831bb002b2ee.jpg)
最近在项目开发当中使用泛型委托Func较多,查看Func的定义就会发现Func的入参都会都会标记上in,出参都会标记上out.
in 和out和泛型类型实参有关, 其中in代表逆变,out代表协变.自己协变和逆变在设计接口或者委托的时候也没有定义过,
因此就详细了解一下其用法.
一.关于协变和逆变
在c# 4.0后,泛型类型参数分为以下三种请情况
1.不变量 这带便泛型参数类型参数不能更改
2.协变量 泛型类型参数可以从一个类更改为它的某个基类.c#中使用out关键字标记协变量形式的泛型类型参数.
协变量泛型类型参数只能出现在输出位置,作为方法的返回类型
3.逆变量 泛型类型参数可以从一个类更改为它的某个派生类.c#中使用in关键字标记逆变量形式的泛型类型参数
逆变量泛型类型参数只能出现在输入位置,作为方法的入参
比如在上述截图的代码中,T1和T2作为委托的入参,Tresult作为委托的出参
二 引入协变逆变
我们看如下代码
![c# 泛型协变逆变学习 - 文章图片](/upload/getfiles/0001/2021/5/6/20210506020430617.jpg)
![c# 泛型协变逆变学习 - 文章图片](/upload/getfiles/0001/2021/5/6/20210506020430693.jpg)
class Program { static void Main(string[] args) { //1. { //List<A> list = new List<B>(); error List<B>并不是List<A>的子类 } //2. { IEnumerable<A> list = new List<B>(); // IEnumerable<B> list1 = new List<A>();// ERROR } //3. { Func<A> func = null; Func<B> func1 = null; func = func1; // func1 = func; ERROR } //4. { Action<A> action = null; Action<B> action1 = null; action1 = action; // action = action1; error } } } public interface A { } public class B : A { }View Code
(1)其中第一个注释部分很明显示编译不过的,因为前后关系并不是继承关系.
(2)第二个编译器能编译通过,第2个不能编译通过,
我们看下 IEnumerable接口的定义
public interface IEnumerable<out T> : IEnumerable
泛型类型前面标识为out
(3)第三个泛型委托中,第1个能编译通过,第二个不能
我们看下Func的定义
public delegate TResult Func<out TResult>();
泛型类型前面标识为out
(4)第四个泛型委托中,第1个能编译通过,第2个不能
我们看下Action的定义
public delegate void Action<in T>(T obj)
泛型类型前面标识为in
以上代码展示了协变和逆变的基本特性
即协变时,泛型类型参数可以从一个类更改为它的某个基类,且该类型仅可作为出参
逆变时,泛型类型参数可以从一个类更改为它的某个派生类,且该类型仅可作为入参
总结
为什必须显示使用in或则out标记类型类型参数,因为我们在编码过程中,需要我们自己去定义协议,
明确告诉编译器允许什么,那么在编译器就能识别出你的泛型类型参数到底能存在什么样的位置上,
若果不用定这个协议,那么编译器在编译时不能识别出,在运行时将会抛出未知的错误.
协变和逆变在设计框架时会有较大的帮助,后续会继续分享在设计框架时协变逆变的用法.
内容总结
以上是互联网集市为您收集整理的c# 泛型协变逆变学习全部内容,希望文章能够帮你解决c# 泛型协变逆变学习所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。