考虑完全实现(?=.*,$)(?:"((?:\\.|[^"])*)"|((?:\\.|[^,])*))(?:[,])
的班级Foo
。
同时,考虑一项任务IFoo
。
为什么调用以下内容时会抛出编译错误;
Task<IFoo>
编译器声明它无法从源类型Task<IFoo> task = Task.Factory.StartNew(() => new Foo());
转换为Task<Foo>
。虽然这是有道理的,因为它们本质上是两种不同的类型,它是否不属于与Task<IFoo>
或其他类似作业相同的前提?
目前我正在强迫演员进入界面,但这感觉不必要。
答案 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());