Reputation: 749
ICollection<T>
implement IEnumerable<T>
and something like this is valid:
ICollection<Computer> Computers {get; set;}
IEnumerable<Computer> Retrieve() => Computers;
But why does the compiler state that implicit conversion is not possible in the following scenario?
ICollection<Computer> Computers {get; set;}
// Error below
// Cannot implicitly convert from Task<ICollection<Computer>> to Task<IEnumerable<Computer>>
Task<IEnumerable<Computer>> RetrieveAsync() => Task.FromResult(Computers);
In order for this to work, I need to call Task.FromResult(Computers.AsEnumerable())
The question is ... why? ICollection<Computer>
is clearly a IEnumerable<Computer>
as well and when it's not wrapped in a Task
implicit conversion works absolutely fine, why would wrapping it in a Task
change anything at all?
Upvotes: 1
Views: 427
Reputation: 8743
Johnathan Barclay explained, why you get this error. If you want to solve it without calling AsEnumerable()
, you can explicitely give the type parameter to the FromResult
method in the Task
class:
Task<IEnumerable<Computer>> RetrieveAsync() => Task.FromResult<IEnumerable<Computer>>(Computers);
Online demo: https://dotnetfiddle.net/0hEnfY
Upvotes: 1
Reputation: 20354
Whilst ICollection<Computer>
is an IEnumerable<Computer>
, a Task<ICollection<Computer>>
is not a Task<IEnumerable<Computer>>
.
This is because for Task<TResult>
, TResult
is invariant.
Covariance and Contravariance in generics
Upvotes: 3