Reputation: 25370
I can do:
public static IEnumerable<string> Do()
{
return new List<string>();
}
But if I'm returning a Task, I'm not allowed to do the same thing:
public static Task<IEnumerable<string>> DoTask()
{
return Task.Factory.StartNew(() =>
{
return new List<string>(); //no no
});
}
I'm implementing a async repository in .NET 4.0 and ran across this. I was just curious why the compiler can't cast my List
down when wrapped in a Task? Of course, my work around is just throwing AsEnumerable
on it , but I wonder why this limitation exists?
Upvotes: 0
Views: 2136
Reputation: 100527
Converting from Task<List<string>>
to Task<IEnumerable<string>>
require Task<T>
to be covariant AND inner types to be interfaces. Neither is true in this case, so conversion not allowed.
Obvious fix - to cast result of Task
to necessary type either by explicitly specifying type for lambda
return Task.Factory.StartNew((Func<IEnumerable<string>>)
(() =>
{
return new List<string>();
}));
or implicitly by casting result:
return (IEnumerable<string>)new List<string>();
Detailed information - Covariance and Contravariance FAQ
Why Task<List<string>>
is result of TaskFactory.StartNew call:
Lambda passed to the StartNew
call does not explicitly specify its type so compiler infers its return type from return
statement. Since return
clearly states new List...
overall type of lambda is equivalent in this case to Func<List<string>>
.
Upvotes: 4