将具体的Task <timplementation>分配给Task <tinterface>类型的变量

时间:2015-05-25 01:54:40

标签: c# inheritance interface casting task-parallel-library

考虑完全实现(?=.*,$)(?:"((?:\\.|[^"])*)"|((?:\\.|[^,])*))(?:[,])的班级Foo。 同时,考虑一项任务IFoo

为什么调用以下内容时会抛出编译错误;

Task<IFoo>

编译器声明它无法从源类型Task<IFoo> task = Task.Factory.StartNew(() => new Foo()); 转换为Task<Foo>。虽然这是有道理的,因为它们本质上是两种不同的类型,它是否不属于与Task<IFoo>或其他类似作业相同的前提?

目前我正在强迫演员进入界面,但这感觉不必要。

2 个答案:

答案 0 :(得分:9)

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

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

请注意,有一个uservoice主题可以做到:"Make Task implement covariant interface ITask"

还要注意以下可能的解释:为什么它现在是这样的,"Lack of Covariance in the Task Class"

  

框架指南是:

     
      
  • 如果你的框架由于其他原因已经包含了一个界面,那么无论如何都要使它成为co + contravariant。
  •   
  • 但是,不要仅为了实现协同+逆转而引入界面。
  •   
     

理由是混淆的劣势超过了协方差的优势(即每个人都必须决定是否在他们的代码中的每个地方都使用Task<T>ITask<T>

现在你必须这样做:

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

答案 1 :(得分:0)

您可以使用通用版

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