分配具体的任务<转换为Task类型的变量

本文关键字:TInterface 变量 Task 类型 转换 任务 分配 | 更新日期: 2023-09-27 17:50:40

考虑一个完全实现IFoo的类Foo。同时考虑任务Task<IFoo>

为什么当调用下列函数时,会抛出编译错误;

Task<IFoo> task = Task.Factory.StartNew(() => new Foo());

编译器提示不能从源类型Task<Foo>转换为Task<IFoo>。虽然这是有道理的,因为它们本质上是两种不同的类型,它不属于相同的前提下的IList<IFoo> list = new List<IFoo>{new Foo(/* construct */)};,或其他类似的任务?

目前我正在强制转换到接口,但这感觉没有必要。

分配具体的任务<转换为Task<TInterface>类型的变量

这是因为语句Task.Factory.StartNew(() => new Foo());返回一个Task<Foo>类型的实例。

并且给定Task<>类是一个具体类,它不能是协变的,除非它实现了协变接口(即ITask<out T>)。

请注意,有一个uservoice主题可以做到这一点:"使任务实现协变接口itask"。

还请注意以下可能的解释,为什么它是现在的方式,"任务类缺乏协方差":

框架指南如下:

  • 如果你的框架因为其他原因已经包含了一个接口,那么无论如何让它变成co+逆变。
  • 但是不要仅仅为了启用co+逆变而引入接口。

理由是协方差的优点被杂乱的缺点所抵消(即每个人都必须决定在代码的每个地方使用Task<T>还是ITask<T>)。

现在你必须这样做:

Task<IFoo> task = Task.Factory.StartNew<IFoo>(() => new Foo());

可以使用通用版本

Task<IFoo> task = Task.Run<IFoo>(() => new Foo());