2016-06-06 4 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) {} 

... где Apple и Orange спускаются с:

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'. Таким образом, вы бы назвали 'Конвертировать (AppleFactory.LoadItems (...))' и 'Конвертировать (OrangeFactory.LoadItems (...))', а затем вызвать 'Task.WhenAll' с двумя результатами. –

+0

Извините, я не читал достаточно внимательно! Дайте ему попробовать ... – Geoff

Смежные вопросы