2016-06-06 50 views
1

我得到一个编译器错误以下行的代码:Task.WhenAll与不同类型的

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

错误CS0029无法隐式转换类型“无效”到 System.Collections.Generic.IEnumerable<IPurchasedItem<IFruit>>[]

我储存库方法如下所示:

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<IEnumerable>[]

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

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

有点相关:http://stackoverflow.com/questions/23766808/why-doesnt-this-exception-get-thrown –

回答

4

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

你可以写一个方法,从一个转换到另一个,当然 - 是这样的:

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

然后您可以将您的所有特定的任务转化为Task<IEnumerable<IPurchasedItem<Fruit>>>任务,而是和然后Task.WhenAll会做什么你要。

+0

谢谢Jon。我稍微更新了我的问题,询问正确的方法是什么,因为这似乎是死路一条。 – Geoff

+2

@Geoff:我已经告诉过你需要正确的方法 - 在调用Task.WhenAll之前,将你的个人任务转换为常见的任务类型。所以你可以调用'Convert (AppleFactory.LoadItems(...))'和Convert (OrangeFactory.LoadItems(...))',然后调用'Task.WhenAll'与两个结果。 –

+0

对不起 - 我没有仔细阅读!给它一个尝试... – Geoff