[英]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> () );
}
此代码无法编译,因为我们无法将 Task<Dictionary<double, double>> 转换为 Task<IDictionary<double, double>>。 为什么这不起作用,是否可以使这种类型的呼叫起作用? 这与像这样编译的方法相反
IDictionary<double, double> GetTaskDict()
{
return new Dictionary<double, double> ();
}
return Task.FromResult<IDictionary<double, double>>(new Dictionary<double, double>());
这是因为Task<T>
不是协变的,因此即使Foo: IFoo
, Task<Foo>
也不能与Task<IFoo>
互换。
如果您要获得大量同步可用的结果,您可能还希望考虑使用ValueTask<T>
- 在这种情况下它要便宜得多。 您甚至可以在该场景中使用隐式new()
用法:
ValueTask<IDictionary<double, double>> GetTaskDict()
{
return new(new Dictionary<double, double>());
}
(这里, new(...)
被解释为new ValueTask<IDictionary<double, double>>(...)
从方法的声明返回类型)
假设这是可能的。
然后有人可以这样做:
Task<IDictionary<double, double>> myTaskDict = new Task<Dictionary<double, double>>();
Task.SetResult(myIDictionaryWhichIsNotActuallyADictionary);
换句话说,正如@MarcGravell 所说, Task
不是协变的,并且有很好的理由。
您可以像这样显式指定类型:
Task<IDictionary<double, double>> GetTaskDict()
{
return Task.FromResult<IDictionary<double, double>>(new Dictionary<double, double>());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.