Dan*_*ark 4 c# inheritance casting interface task-parallel-library
考虑一个Foo完全实现的类IFoo.同时,考虑一项任务Task<IFoo>.
为什么在调用以下内容时会抛出编译错误;
Task<IFoo> task = Task.Factory.StartNew(() => new Foo());
Run Code Online (Sandbox Code Playgroud)
编译器声明它无法从源类型转换Task<Foo>为Task<IFoo>.虽然这是有道理的,因为它们本质上是两种不同的类型,它不会与IList<IFoo> list = new List<IFoo>{new Foo(/* construct */)};其他类似的任务处于相同的前提下吗?
目前我正在强迫演员进入界面,但这感觉不必要.
那是因为这个语句Task.Factory.StartNew(() => new Foo());返回一个类型的实例Task<Foo>.
并且鉴于Task<>该类是具体类,它不能是协变的,除非它实现了协变接口(即ITask<out T>).
请注意,有一个uservoice主题可以做到:"使任务实现协变接口ITask".
还要注意以下可能的解释,为什么它现在的方式,"任务类缺乏协方差":
框架指南是:
- 如果你的框架由于其他原因已经包含了一个接口,那么无论如何都要使它成为co + contravariant.
- 但是,不要仅为了实现协同+逆转而引入接口.
其理由是,协方差的好处是杂乱的缺点抵销(即每个人都必须做出有关是否使用的决定
Task<T>或ITask<T>在他们的代码中的每一个地方).
现在你必须这样做:
Task<IFoo> task = Task.Factory.StartNew<IFoo>(() => new Foo());
Run Code Online (Sandbox Code Playgroud)