Csharp/C#教程:为什么async / await允许从List到IEnumerable的隐式转换?分享


为什么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

但是,如果tTask ,则await t的类型为T ,如果T : UT : U可以转换为U

很明显你明白为什么List至少可以作为IEnumerable返回:只是因为它实现了那个接口。

同样清楚的是,第三个例子是做一些“额外”的事情,而第四个例子则没有。 正如其他人所说,第四次失败是因为缺乏协方差(或者反之,我永远不会记得他们Task> !),因为你直接试图提供一个Task>的实例作为Task>一个实例。

第三次传递的原因是因为await添加了大量的“支持代码”以使其按预期工作。 此代码将Task解析为T ,这样return await Task将返回通用Task关闭的类型,在这种情况下something

然后方法签名返回Task并且它的工作原理再次由编译器解决,这需要TaskTaskvoid for async方法,并简单地将你的T按摩回到Task作为所有的一部分背景生成asyn / await continuation gubbins。

这是一个额外的步骤,从await中获取T并需要将其转换 Task ,从而为其提供所需的空间。 您不是试图使用Task的现有实例来满足Task ,而是创建一个全新的Task ,给它一个U : T ,并且在构造时隐式转换发生为你会期望(以与你期望的完全相同的方式IEnumerable myVar = new List();来工作)。

怪/感谢编译器,我经常这样做;-)

上述就是C#学习教程:为什么async / await允许从List到IEnumerable的隐式转换?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/958050.html

(0)
上一篇 2021年11月22日
下一篇 2021年11月22日

精彩推荐