使用 Task.FromResult 将 Task<T> 隐式转换为 Task<X>,其中 T : X?

Vin*_*wis 3 c# inheritance task

Task<IDictionary<double, double>> GetTaskDict()
{
     return Task.FromResult(new Dictionary<double, double> () );
}
Run Code Online (Sandbox Code Playgroud)

这段代码无法编译,因为我们无法在 Task<Dictionary<double, double>> 到 Task<IDictionary<double, double>> 之间进行转换。为什么这不起作用,是否可以使这种类型的呼叫起作用?这与这样的编译方法相反

IDictionary<double, double> GetTaskDict()
{
     return new Dictionary<double, double> ();
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 5

return Task.FromResult<IDictionary<double, double>>(new Dictionary<double, double>());
Run Code Online (Sandbox Code Playgroud)

这是因为Task<T>不是协变的,所以 aTask<Foo>不能与 a 互换,Task<IFoo>即使Foo : IFoo

ValueTask<T>如果您要获得大量同步可用的结果,您可能还希望考虑使用- 在这种情况下它要便宜得多。您甚至可以new()在该场景中使用隐式用法:

ValueTask<IDictionary<double, double>> GetTaskDict()
{
    return new(new Dictionary<double, double>());
}
Run Code Online (Sandbox Code Playgroud)

(这里,new(...)被解释为new ValueTask<IDictionary<double, double>>(...)从方法的声明返回类型)