简体   繁体   English

使用 Task.FromResult 隐式转换任务<t>到一个任务<x> T:X?</x></t>

[英]Using Task.FromResult to implicitly convert a Task<T> to a Task<X> where T : X?

Task<IDictionary<double, double>> GetTaskDict()
{
     return Task.FromResult(new Dictionary<double, double> () );
}

This code does not compile because we can not convert between Task<Dictionary<double, double>> to Task<IDictionary<double, double>>.此代码无法编译,因为我们无法将 Task<Dictionary<double, double>> 转换为 Task<IDictionary<double, double>>。 Why does this not work, and is it possible to make this type of call work?为什么这不起作用,是否可以使这种类型的呼叫起作用? This opposed to a method like this which compiles这与像这样编译的方法相反

IDictionary<double, double> GetTaskDict()
{
     return new Dictionary<double, double> ();
}
return Task.FromResult<IDictionary<double, double>>(new Dictionary<double, double>());

This is because Task<T> is not covariant, so a Task<Foo> is not interchangeable with a Task<IFoo> even if Foo: IFoo .这是因为Task<T>不是协变的,因此即使Foo: IFooTask<Foo>也不能与Task<IFoo>互换。

You may also wish to consider using ValueTask<T> if you're going to have lots of results which are available synchronously - it is significantly cheaper in that scenario.如果您要获得大量同步可用的结果,您可能还希望考虑使用ValueTask<T> - 在这种情况下它要便宜得多。 You can even use the implicit new() usage in that scenario:您甚至可以在该场景中使用隐式new()用法:

ValueTask<IDictionary<double, double>> GetTaskDict()
{
    return new(new Dictionary<double, double>());
}

(here, new(...) is interpreted as new ValueTask<IDictionary<double, double>>(...) from the declared return-type of the method) (这里, new(...)被解释为new ValueTask<IDictionary<double, double>>(...)从方法的声明返回类型)

Suppose it were possible.假设这可能的。

Then someone could do this:然后有人可以这样做:

Task<IDictionary<double, double>> myTaskDict = new Task<Dictionary<double, double>>();

Task.SetResult(myIDictionaryWhichIsNotActuallyADictionary);

In other words, as @MarcGravell has said, Task is not covariant, and for very good reason.换句话说,正如@MarcGravell 所说, Task不是协变的,并且有很好的理由。


You can specify the type explicitly like this though:可以像这样显式指定类型:

Task<IDictionary<double, double>> GetTaskDict()
{
     return Task.FromResult<IDictionary<double, double>>(new Dictionary<double, double>());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM