使用 Task.FromResult 将 Task<T> 隐式转换为 Task<X>,其中 T : X?
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> 与 Task> 之间进行转换。为什么这不起作用,是否可以使这种类型的呼叫起作用?这与编译
这样的方法相反
IDictionary<double, double> GetTaskDict()
{
return new Dictionary<double, double> ();
}
return Task.FromResult<IDictionary<double, double>>(new Dictionary<double, double>());
这是因为 Task<T>
不是协变的,所以 Task<Foo>
不能与 Task<IFoo>
互换,即使 Foo : IFoo
.
如果您要获得大量同步可用的结果,您可能还希望考虑使用 ValueTask<T>
- 在这种情况下成本要低得多。您甚至可以在该场景中使用隐式 new()
用法:
ValueTask<IDictionary<double, double>> GetTaskDict()
{
return new(new Dictionary<double, double>());
}
(这里,new(...)
从声明的 return 方法类型中解释为 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>());
}
Task<IDictionary<double, double>> GetTaskDict()
{
return Task.FromResult(new Dictionary<double, double> () );
}
此代码无法编译,因为我们无法在 Task
IDictionary<double, double> GetTaskDict()
{
return new Dictionary<double, double> ();
}
return Task.FromResult<IDictionary<double, double>>(new Dictionary<double, double>());
这是因为 Task<T>
不是协变的,所以 Task<Foo>
不能与 Task<IFoo>
互换,即使 Foo : IFoo
.
如果您要获得大量同步可用的结果,您可能还希望考虑使用 ValueTask<T>
- 在这种情况下成本要低得多。您甚至可以在该场景中使用隐式 new()
用法:
ValueTask<IDictionary<double, double>> GetTaskDict()
{
return new(new Dictionary<double, double>());
}
(这里,new(...)
从声明的 return 方法类型中解释为 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>());
}