为什么异步/计谋允许从列表中IEnumerable的隐式转换?计谋、隐式、列表中、IEnumerable

2023-09-04 09:41:49 作者:異性好友

我刚刚被玩弄异步/等待,并发现了一些有趣的事情。看看下面的例子:

I've just been playing around with async/await and found out something interesting. Take a look at the examples below:

// 1) ok - obvious
public Task<IEnumerable<DoctorDto>> GetAll()
{
    IEnumerable<DoctorDto> doctors = new List<DoctorDto>
    {
        new DoctorDto()
    };

    return Task.FromResult(doctors);
}

// 2) ok - obvious
public async Task<IEnumerable<DoctorDto>> GetAll()
{
    IEnumerable<DoctorDto> doctors = new List<DoctorDto>
    {
        new DoctorDto()
    };

    return await Task.FromResult(doctors);
}

// 3) ok - not so obvious
public async Task<IEnumerable<DoctorDto>> GetAll()
{
    List<DoctorDto> doctors = new List<DoctorDto>
    {
        new DoctorDto()
    };

    return await Task.FromResult(doctors);
}

// 4) !! failed to build !!
public Task<IEnumerable<DoctorDto>> GetAll()
{
    List<DoctorDto> doctors = new List<DoctorDto>
    {
        new DoctorDto()
    };

    return Task.FromResult(doctors);
}

考虑例3和4。唯一的区别在于,使用3异步/等待关键字。 3建立正常,但是4提供了有关一个列表的隐式转换为IEnumerable的错误:

Consider cases 3 and 4. The only difference is that 3 uses async/await keywords. 3 builds fine, however 4 gives an error about implicit conversion of a List to IEnumerable:

Cannot implicitly convert type 
'System.Threading.Tasks.Task<System.Collections.Generic.List<EstomedRegistration.Business.ApiCommunication.DoctorDto>>' to 
'System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<EstomedRegistration.Business.ApiCommunication.DoctorDto>>'  

它是什么,异步/等待关键字在此更改?

What is it that async/await keywords change here?

推荐答案

任务&LT; T&GT; 根本就不是一个协变型

Task<T> is simply not a covariant type.

尽管名单,其中,T&GT; 可以被转换成的IEnumerable&LT; T&GT; 任务&LT ;列表&LT; T&GT;&GT; 粗野,被转换为任务&LT; IEnumerable的&LT; T&GT;&GT; 。而在#4, Task.FromResult(医生)返回任务&LT;列表&LT; D​​octorDto&GT;&GT;

Although List<T> can be converted to IEnumerable<T>, Task<List<T>> connot be converted to Task<IEnumerable<T>>. And In #4, Task.FromResult(doctors) returns Task<List<DoctorDto>>.

在#3,我们有:

return await Task.FromResult(doctors)

这是一样的:

Which is the same as:

return await Task<List<DoctorDto>>.FromResult(doctors)

这是一样的:

Which is the same as:

List<DoctorDto> result = await Task<List<DoctorDto>>.FromResult(doctors);
return result;

这工作,因为名单,其中,DoctorDto&GT; 可转换的IEnumerable&LT; D​​octorDto&GT;