C#:关于C#4中IEnumerable<out T>的理解

IEnumerable<out T>这个接口非常常见,它是最基础的泛型集合接口,表示可迭代的项的序列。

但是奇怪的是为什么泛型参数要带一个“out”?

经过一番资料查阅后,发现此“out”和C#中的“out”类型参数的“out”并非一个意思。

IEnumerable<out T>中的out表示这个接口支持“协变性”。

何谓“协变性”?

简单的理解就是“T”可以变化为T的基类型。说了这么多,感觉还是很抽象,用一段代码表示吧。

IEnumerable<int> collection1 = new List<string>();
IEnumerable<object> collection2 = collection1;
在C#4.0之前,由于IEnumerable<T>的声明并未包含“out”关键字,所以上面的代码是无法通过编译的,编译器会告知你类型转换失败,因为collection2对应的类型为IEnumerable<object>,而collection1对应的类型为IEnumerable<int>。
其实这个问题并不是多么深刻,因为现在绝大部分C#开发者用的都是C# 5,就会很“理所当然”的觉得collection1可以转化为collection2。我也是,直至查阅资料研究“out”这个关键字才发现之所以可以实现这样转换的原因。

转载声明:本文转载自http://www.zhoumy.cn/?p=16
时间: 2024-10-21 14:50:03

C#:关于C#4中IEnumerable<out T>的理解的相关文章

JAVA 中BIO,NIO,AIO的理解

JAVA 中BIO,NIO,AIO的理解 博客分类: 网络编程 [转自]http://qindongliang.iteye.com/blog/2018539 在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什么是同步阻塞? 6 什么是同步非阻塞? 7 什么是异步阻塞? 8 什么是异步非阻塞? 散仙不才,在查了一部分资料后,愿试着以通俗易懂的方式解释下这几个名词.如有不足之处,还

android 学习过程中登陆失效的个人理解

今天在学习的过程中,要做登陆失效的功能,所以就找了些资料,好好看了一下,研究了一番,慢慢的做出来了! 比如:你在一个手机端登陆了账号,在另外的一个手机端也登陆了账号,此时,前一个手机端的账号会提示登陆失效. 意思是只能存在一个账号,这个其实不是很难. 每次登陆的时候会存在一个Token,每次登陆的Token是不一样的! 下面贴一下前端的一些小代码: 在异步网络请求里面判断返回的异常是否是登陆失效: @Override protected void onPostExecute(BusinessRe

android中padding和margin的理解

在android安排控件布局时,padding和margin经常被用到. 其具体解释可以通过一张图展现,如下, 两个属性表示的意义与web编程相同. 深入理解: padding约束的是控件或布局显示的内容距离边框的距离,沿垂直边框向内压缩,padding越大,内容显示控件越小: margin这是沿垂直边框向外延伸的距离, 它的意思就是给控件加了一个一定距离的空白边,显示效果只与值大小正负相关,与其他元素边界无关. 值得注意的是,padding值的范围[0,任意正数](默认为0),而margin的

关于Java中继承和接口的理解

关于Java中继承和接口的理解 Java语言中,为了实现代码重用,设计了继承这一机制,但是,其设计成单继承,这样设计是有原因的,如下图: Figure1:deadly diamond of death 此图问题称为菱形问题(diamond problem),就是说,当A的子类B和C同时实现了A中的方法,则同时继承了B和C的子类D在调用该方法时会出现混乱,无法得知该调用哪一个方法. 既然不能实现多继承,我们就会考虑把很多方法就写在父类里,或者继承抽象类,实现其方法,但是,这样会导致一个问题,比如说

【转】C#中对IDisposable接口的理解

IDisposable接口定义:定义一种释放分配的资源的方法. .NET 平台在内存管理方面提供了GC(Garbage Collection),负责自动释放托管资源和内存回收的工作,但它无法对非托管资源进行释放,这时我们必须自己提供方法来释放对象内分配的非托管资源,比如你在对象的实现代码中使用了一个COM对象 最简单的办法可以通过实现Finalize()来释放非托管资源,因为GC在释放对象时会检查该对象是否实现了 Finalize() 方法. 有一种更好的,那就是通过实现一个接口显式的提供给客户

javascript中 的 + RegExp[&#39;\x241&#39;] 怎么理解

\x24是十六进制转义符,16*2+4=36,ASCII码36代表的正是“$”符号(可以查ASCII码表),十六进制转义符的一般形式是'\xhh',h是0-9或A-F内的一个.$1是javascript全局对象 RegExp 的属性(可以查javascript API RegExp 对象),返回在模式匹配期间找到的.最近保存的部分+ 相当于 Number()函数(试了几种类型,两者效果一致,但不能确定). javascript正则表达式语法:\xn 匹配 n,其中 n 为十六进制转义值.十六进制

Oracle中B-TREE索引的深入理解(转载)

索引概述 索引与表一样,也属于段(segment)的一种.里面存放了用户的数据,跟表一样需要占用磁盘空间.只不过,在索引里的数据存放形式与表里的数据存放形式非常的不一样.在理解索引时,可以想象一本书,其中书的内容就相当于表里的数据,而书前面的目录就相当于该表的索引.同时,通常情况下,索引所占用的磁盘空间要比表要小的多,其主要作用是为了加快对数据的搜索速度,也可以用来保证数据的唯一性.但是,索引作为一种可选的数据结构,你可以选择为某个表里的创建索引,也可以不创建.这是因为一旦创建了索引,就意味着o

Android中BindService方式使用的理解

Android中BindService方式使用的理解 - 唯一小神 - 博客园 最近学习了一下Android里面的Service的应用,在BindService部分小卡了一下,主要是开始没有彻底理解为什么要这么实现. BindService和Started Service都是Service,有什么地方不一样呢: 1. Started Service中使用StartService()方法来进行方法的调用,调用者和服务之间没有联系,即使调用者退出了,服务依然在进行[onCreate()-? >onS

Vue中对生命周期的理解

Vue中对生命周期的理解 1. 实例.组件通过new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载ね,只是一个空壳,无法访问到数据和真实的dom,一般不做操作 2. 挂载数据,绑定事件等等,然后执行created函数,这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发updated函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取 3. 接下来开始找实例