将具体任务<TImplementation>分配给类型任务<TInterface>的变量
Assigning a concrete Task<TImplementation> to a variable of type Task<TInterface>
考虑一个 class 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<IFoo> task = Task.Run<IFoo>(() => new Foo());
那是因为这个语句Task.Factory.StartNew(() => new Foo());
returns类型的一个实例Task<Foo>
.
鉴于 Task<>
class 是一个具体的 class,它不能是协变的,除非它正在实现一个协变接口(即 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());
考虑一个 class 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<IFoo> task = Task.Run<IFoo>(() => new Foo());
那是因为这个语句Task.Factory.StartNew(() => new Foo());
returns类型的一个实例Task<Foo>
.
鉴于 Task<>
class 是一个具体的 class,它不能是协变的,除非它正在实现一个协变接口(即 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>
orITask<T>
in every single place in their code).
现在您需要做的是:
Task<IFoo> task = Task.Factory.StartNew<IFoo>(() => new Foo());