2016-06-06 49 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