c# - 将具体的 Task<TImplementation> 分配给 Task<TInterface> 类型的变量

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

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

为什么调用下面的时候会抛出编译错误;

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

编译器声明它无法从源类型转换 Task<Foo>Task<IFoo> .虽然这是有道理的,因为它们本质上是两种不同的类型,但它不会属于与 IList<IFoo> list = new List<IFoo>{new Foo(/* construct */)}; 相同的前提吗? ,或其他类似的作业?

目前我正在强制对界面进行强制转换,但这感觉没有必要。

最佳答案

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

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

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

另请注意以下可能的解释,说明为什么现在是这样,"Lack of Covariance in the Task Class" :

Framework guidelines are:

  • If your framework already includes an interface for other reasons, then by all means make it co+contravariant.
  • But don't introduce an interface solely for the purposes of enabling co+contravariance.

The justification is that the advantage of covariance is outweighed by the disadvantage of clutter (i.e. everyone would have to make a decision about whether to use Task<T> or ITask<T> in every single place in their code).

现在你必须做:

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

关于c# - 将具体的 Task<TImplementation> 分配给 Task<TInterface> 类型的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30430267/

相关文章:

c# - C#计算两年间的闰年数

c# - 没有 "line break"的 FlowLayoutPanel

C++ - 继承和初始化问题

java - 在 GWT 项目中使用常量接口(interface)

c++ - 当有其他虚拟基类时如何避免对基类函数的模糊调用

java - 这个叫什么?这是设计模式还是约定? (接口(interface)/类)

c# - 将 DialogViewController 推送到 ViewController 到 NavigationController 堆栈上会产生 2 页

c# - 如何使用包含的源代码生成器发布 .Net 库?

java - 为什么签名指定接口(interface)时会调用父类(super class)方法?

javascript - 如何在父类(super class)静态函数中引用子类的静态参数?