从任务

时间:2015-06-05 14:27:39

标签: c# casting task ienumerable

我能做到:

public static IEnumerable<string> Do()
{
   return new List<string>();
}

但是,如果我回复任务,我不允许做同样的事情:

public static Task<IEnumerable<string>> DoTask()
{
    return Task.Factory.StartNew(() =>
    {
        return new List<string>(); //no no
    });
}

我在.NET 4.0中实现了异步存储库并遇到了这个问题。我只是好奇为什么编译器在包装在一个任务中时无法将我的List强制转换?当然,我的工作只是抛出AsEnumerable,但我想知道为什么存在这种限制?

1 个答案:

答案 0 :(得分:4)

Task<List<string>>转换为Task<IEnumerable<string>>需要Task<T>为协变且内部类型为接口。在这种情况下都不是这样,所以不允许转换。

明显的修复 - 通过显式指定lambda的类型将Task的结果转换为必要的类型

return Task.Factory.StartNew((Func<IEnumerable<string>>)
  (() =>
  {
    return new List<string>(); 
  }));

或隐式地通过投射结果:

  return (IEnumerable<string>)new List<string>();

详细信息 - Covariance and Contravariance FAQ

为什么Task<List<string>>是TaskFactory.StartNew调用的结果:

传递给StartNew调用的Lambda没有明确指定其类型,因此编译器会从return语句中推断出它的返回类型。由于return明确指出new List...整体类型的lambda在这种情况下等同于Func<List<string>>