JohnUbuntu
JohnUbuntu

Reputation: 749

Implicit conversion from ICollection<T> to IEnumerable<T>

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

Answers (2)

SomeBody
SomeBody

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

Johnathan Barclay
Johnathan Barclay

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

Related Questions