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>()
};