为什么async / await允许从List到IEnumerable的隐式转换?
我一直在玩async / await,发现了一些有趣的东西。 看看下面的例子:
// 1) ok - obvious public Task<IEnumerable> GetAll() { IEnumerable doctors = new List { new DoctorDto() }; return Task.FromResult(doctors); } // 2) ok - obvious public async Task<IEnumerable> GetAll() { IEnumerable doctors = new List { new DoctorDto() }; return await Task.FromResult(doctors); } // 3) ok - not so obvious public async Task<IEnumerable> GetAll() { List doctors = new List { new DoctorDto() }; return await Task.FromResult(doctors); } // 4) !! failed to build !! public Task<IEnumerable> GetAll() { List doctors = new List { new DoctorDto() }; return Task.FromResult(doctors); }
考虑案例3和4.唯一的区别是3使用async / await关键字。 3构建正常,但4给出了关于List隐式转换为IEnumerable的错误:
Cannot implicitly convert type 'System.Threading.Tasks.Task<System.Collections.Generic.List>' to 'System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable>'
什么是async / await关键字在这里改变了?
Task
根本不是协变类型。
虽然List
可以转换为IEnumerable
,但Task
不能转换为>
Task
。 在#4中, Task.FromResult(doctors)
返回Task
。 >
在#3中,我们有:
return await Task.FromResult(doctors)
这与:
return await Task>.FromResult(doctors)
这与:
List result = await Task>.FromResult(doctors); return result;
这是有效的,因为List
可以转换为IEnumerable
。
想想你的类型。 Task
不是变体,因此它不能转换为Task
,即使T : U
。
但是,如果t
是Task
,则await t
的类型为T
,如果T : U
则T : U
可以转换为U
很明显你明白为什么List
至少可以作为IEnumerable
返回:只是因为它实现了那个接口。
同样清楚的是,第三个例子是做一些“额外”的事情,而第四个例子则没有。 正如其他人所说,第四次失败是因为缺乏协方差(或者反之,我永远不会记得他们Task
!),因为你直接试图提供一个>
Task
的实例作为>
Task
一个实例。
第三次传递的原因是因为await
添加了大量的“支持代码”以使其按预期工作。 此代码将Task
解析为T
,这样return await Task
将返回通用Task
关闭的类型,在这种情况下something
。
然后方法签名返回Task
并且它的工作原理再次由编译器解决,这需要Task
, Task
或void
for async方法,并简单地将你的T
按摩回到Task
作为所有的一部分背景生成asyn / await continuation gubbins。
这是一个额外的步骤,从await
中获取T
并需要将其转换回 Task
,从而为其提供所需的空间。 您不是试图使用Task
的现有实例来满足Task
,而是创建一个全新的Task
,给它一个U : T
,并且在构造时隐式转换发生为你会期望(以与你期望的完全相同的方式IEnumerable
来工作)。
怪/感谢编译器,我经常这样做;-)
上述就是C#学习教程:为什么async / await允许从List到IEnumerable的隐式转换?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/958050.html