正如标题所述,我很好奇是否可以从Task<List<Derived>>
转换为Task<List<BaseType>>
?
我有几个返回Task<List<Derived>>
的方法,并且可以有多个类型的派生类。我想将所有任务存储在一个任务列表中:List<Task<List<BaseType>>>
将在以后执行。
如果我的任务不是包装列表,那么这将非常简单:link
修改1
以下是我遇到问题的部分,我在列表中存储任务时遇到问题:
// This throws an error (cannot convert derived list to base list)
var tasks = new List<Task<List<BaseType>>>
{
asyncThing1(), // returns Task<List<Derived1>>
asyncThing2(), // returns Task<List<Derived2>>
// ... n number more
};
// Need the list of tasks before I can execute
List<BaseType>[] results = await Task.WhenAll(tasks);
修改2
在上方,将List<Base>[]
更改为List<BaseType>[]
答案 0 :(得分:4)
正如标题所述,我很好奇是否可以从
Task<List<Derived>>
转换为Task<List<Base>>
?
没有。假设它是合法的,看看出了什么问题:
Task<List<Giraffe>> t1 = GetGiraffesAsync();
Task<List<Animal>> t2 = t1; // Suppose this were legal
(await t2).Add(new Fish());
现在我们在长颈鹿名单中有一条鱼。
这三条线中的一条必须是非法的。显然它不是第一个,因为GetGiraffesAsync
返回Task<List<Giraffe>>
。显然它不可能是最后一个,因为await t2
产生List<Animal>
,而鱼是动物。因此,它必须是非法的中间线。
现在,您可以这样做:
async Task<List<Animal>> ConvertAsync(Task<List<Giraffe>> t) =>
(await t).Select(g => (Animal)g).ToList();
或者
async Task<List<Animal>> ConvertASync(Task<List<Giraffe>> t) =>
(await t).Cast<Animal>().ToList();
或
async Task<List<Animal>> ConvertAsync(Task<List<Giraffe>> t) =>
(await t).OfType<Animal>().ToList();
如果你想让它变得通用,你可以做到
async Task<<List>Animal> ConvertAsync<T>(Task<List<T>> t) where T : Animal =>
(await t).OfType<Animal>().ToList();
现在它适用于长颈鹿和鱼类和老虎等。
也就是说,您可以异步等待原始任务完成,完成后,您可以从长颈鹿列表中创建新的动物列表。这完全合法。你现在有两个列表,一个长颈鹿和一个动物。
或者,你可以这样做:
async Task<IEnumerable<Animal>> ConvertAsync(Task<List<Giraffe>> t) =>
await t;
因为List<Giraffe>
可转换为IEnumerable<Animal>
。
我倾向于将其作为扩展方法编写。
static class Extensions {
public static Task<List<Animal>> ConvertAsync<T>(
this Task<List<T>> t) where T : Animal {
return (await t).OfType<Animal>().ToList();
}
}
现在您的程序片段是:
var tasks = new List<Task<List<Animal>>>
{
GetGiraffesAsync().ConvertAsync(),
GetTigersAsync().ConvertAsync()
};
答案 1 :(得分:2)
正如一点注意事项,您发布的链接只是缺少List部分,以使其适用于您的场景。
所以这是在另一个主题中提出的: Cannot convert type 'Task<Derived>' to 'Task<Interface>'
async Task<TBase> GeneralizeTask<TBase, TDerived>(Task<TDerived> task)
where TDerived : TBase
{
return (TBase) await task;
}
您要搜索的是:
async Task<List<TBase>> GeneralizeTask<TBase, TDerived>(Task<List<TDerived>> task)
where TDerived : TBase
{
return (await task).Cast<TBase>().ToList();
}
你可以这样称呼它:
var tasks = new List<Task<List<Animal>>>
{
GetGiraffesAsync().GeneralizeTask<Animal, Giraffe>(),
GetTigersAsync().GeneralizeTask<Animal, Tiger>()
};