【问题标题】:Task.WhenAll With Different TypesTask.WhenAll 不同类型
【发布时间】:2016-06-06 19:52:05
【问题描述】:

我收到以下代码行的编译器错误:

IEnumerable<IPurchasedItem<IFruit>>[] result = await Task.WhenAll(
                repository1.LoadItems(id),
                repository2.LoadItems(id)
                );

错误 CS0029 无法将类型“void”隐式转换为 System.Collections.Generic.IEnumerable&lt;IPurchasedItem&lt;IFruit&gt;&gt;[]

我的存储库方法如下所示:

public async Task<IEnumerable<IPurchasedItem<Apple>>> LoadItems(int id) {}
public async Task<IEnumerable<IPurchasedItem<Orange>>> LoadItems(int id) {}

...AppleOrange 来自:

public interface IPurchasedItem<out T> : where T : IFruit {}
public class Fruit : IFruit {}
public class Apple : Fruit {}
public class Orange : Fruit {}

我查看了this question,但似乎我已经在按照建议进行操作,即请求IEnumerable[] 而不是Task&lt;IEnumerable&gt;[]

我做错了什么 - 如果这不是正确的方法,那么我等待并结合 LoadItems() 方法的结果的最佳方法是什么? 我原本打算这样做:

result[0].Concat(result[1])

【问题讨论】:

标签: c# async-await


【解决方案1】:

Task&lt;T&gt; 是一个类,因此是不变的。所以Task&lt;string&gt; 不是Task&lt;object&gt; - 作为一个更复杂的例子,Task&lt;IEnumerable&lt;IPurchasedItem&lt;Apple&gt;&gt;&gt; 不是Task&lt;IEnumerable&lt;IPurchasedItem&lt;Fruit&gt;&gt;&gt;,这是你想要的。

当然,您可以编写一种方法来从一种转换为另一种,例如:

public static Task<TTarget> Convert<TSource, TTarget>(Task<TSource> task)
    where TSource : TTarget
{
    return await task;
}

然后您可以将所有特定任务转换为 Task&lt;IEnumerable&lt;IPurchasedItem&lt;Fruit&gt;&gt;&gt; 任务,然后 Task.WhenAll 会做您想做的事情。

【讨论】:

  • 谢谢乔恩。我稍微更新了我的问题以询问正确的方法是什么,因为这似乎是一个死胡同。
  • @Geoff:我已经告诉过你想要正确的方法是 - 在调用 Task.WhenAll 之前将你的单个任务转换为通用任务类型。所以你会打电话给Convert&lt;Apple, Fruit&gt;(AppleFactory.LoadItems(...))Convert&lt;Orange, Fruit&gt;(OrangeFactory.LoadItems(...)),然后用这两个结果调用Task.WhenAll
  • 这很好 - 感谢您的反击,让我更加努力地思考 :)
猜你喜欢
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-22
  • 2018-04-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多