Consider a class Foo which wholly implements IFoo.
Concurrently, consider a task Task<IFoo>.
Why is it that when the following is called, a compilation error is thrown;
Task<IFoo> task = Task.Factory.StartNew(() => new Foo());
The compiler states that it cannot convert from source type Task<Foo> to Task<IFoo>. While this makes sense because they are essentially two differing types, would it not fall under the same premise as IList<IFoo> list = new List<IFoo>{new Foo(/* construct */)};, or other similar assignments?
At the moment I am forcing a cast to the interface, but this feels unneccesary.
That is because this statement Task.Factory.StartNew(() => new Foo()); returns an instance of type Task<Foo>.
And given that the Task<> class is a concrete class, it cannot be covariant, unless it were implementing a covariant interface (i.e. ITask<out T>).
Note that there is a uservoice topic to do just that: "Make Task implement covariant interface ITask".
Also note the following possible explanation on why it is the way is it now, "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).
For now you will have to do:
Task<IFoo> task = Task.Factory.StartNew<IFoo>(() => new Foo());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With