C# 如何从任务转换<;列表<;派生>&燃气轮机;任务<;列表<;基地>&燃气轮机;
正如标题所述,我很好奇是否可以从C# 如何从任务转换<;列表<;派生>&燃气轮机;任务<;列表<;基地>&燃气轮机;,c#,generics,asynchronous,async-await,C#,Generics,Asynchronous,Async Await,正如标题所述,我很好奇是否可以从任务转换为任务 我有几个方法返回任务,可以有多种类型的派生类。我想将所有任务存储在一个任务列表中:list稍后执行 如果我的任务不是包装列表,这将是非常直接的: 编辑1 以下是我遇到的问题,我在列表中存储任务时遇到问题: // This throws an error (cannot convert derived list to base list) var tasks = new List<Task<List<BaseType>>
任务
转换为任务
我有几个方法返回任务
,可以有多种类型的派生类。我想将所有任务存储在一个任务列表中:list
稍后执行
如果我的任务不是包装列表,这将是非常直接的:
编辑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);
//这会引发错误(无法将派生列表转换为基列表)
var tasks=新列表
{
asyncThing1(),//返回任务
asyncThing2(),//返回任务
//…还有多少
};
//我需要任务列表才能执行
List[]results=等待任务。WhenAll(任务);
编辑2
上面,将List[]
更改为List[]
正如标题所述,我很好奇是否可以从任务
转换为任务
不,假设它是合法的,看看出了什么问题:
Task<List<Giraffe>> t1 = GetGiraffesAsync();
Task<List<Animal>> t2 = t1; // Suppose this were legal
(await t2).Add(new Fish());
或
异步任务转换异步(任务t)=>
(等待t)Cast().ToList();
或
异步任务转换异步(任务t)=>
(等待t)of type().ToList();
如果你想让它通用,你可以这样做
async Task<<List>Animal> ConvertAsync<T>(Task<List<T>> t) where T : Animal =>
(await t).OfType<Animal>().ToList();
async Task ConvertAsync(Task t),其中t:Animal=>
(等待t)of type().ToList();
现在它可以与长颈鹿、鱼、老虎等动物合作
也就是说,您可以异步等待原始任务完成,完成后,您可以从长颈鹿列表中创建新的动物列表。这是完全合法的。您现在有两个列表,一个是长颈鹿,另一个是动物
或者,您可以这样做:
async Task<List<Animal>> ConvertAsync(Task<List<Giraffe>> t) =>
(await t).Select(g => (Animal)g).ToList();
async Task<IEnumerable<Animal>> ConvertAsync(Task<List<Giraffe>> t) =>
await t;
异步任务转换异步(任务t)=>
等待t;
因为列表
可转换为IEnumerable
我倾向于将其作为扩展方法编写
static class Extensions {
public static Task<List<Animal>> ConvertAsync<T>(
this Task<List<T>> t) where T : Animal {
return (await t).OfType<Animal>().ToList();
}
}
静态类扩展{
公共静态任务转换异步(
本任务t)其中t:动物{
return(wait t).OfType().ToList();
}
}
现在你的程序片段是:
var tasks = new List<Task<List<Animal>>>
{
GetGiraffesAsync().ConvertAsync(),
GetTigersAsync().ConvertAsync()
};
var任务=新列表
{
GetGiraffesAsync().ConvertAsync(),
GetTigerAsync().ConvertAsync()
};
作为一个小小的旁注,您发布的链接只是缺少列表部分,以使其适用于您的场景
所以这是在另一个主题中提出的:
异步任务泛化任务(任务任务)
来源:TBase
{
返回(TBase)等待任务;
}
您正在搜索的是:
async Task<List<TBase>> GeneralizeTask<TBase, TDerived>(Task<List<TDerived>> task)
where TDerived : TBase
{
return (await task).Cast<TBase>().ToList();
}
异步任务泛化任务(任务任务)
来源:TBase
{
return(等待任务).Cast().ToList();
}
你可以这样称呼它:
var tasks = new List<Task<List<Animal>>>
{
GetGiraffesAsync().GeneralizeTask<Animal, Giraffe>(),
GetTigersAsync().GeneralizeTask<Animal, Tiger>()
};
var任务=新列表
{
GetGiraffesAsync().GeneralizeTask(),
GetTigerAsync().GeneralizeTask()
};
为什么不直接获取任务的结果
,然后将列表
转换为列表
?等待您的任务().Cast().ToList()
?@RandRandom反过来,您可以将其简化为列表.Cast
是,因此,等待它们全部完成,然后您就可以处理结果了。@RandRandom您需要像(wait YourTask()).Cast().ToList()
这样做,以确保先打开任务。扩展方法正是我要找的。谢谢你解释得很好的回答!是的,这就是我要找的。我不认为我的问题是重复的,因为它现在似乎已经被标记了。谢谢你添加这个。
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>()
};