简体   繁体   中英

Returning IEnumerable Implementation from within Task

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?

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>> .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM