我一直在重构我的项目中的一个常见模式,发现它不像使用 LINQ Select
那样简单。到异步函数。
对于上下文,这是当前的完成方式。
async Task<ICollection<Group>> ExecuteQueryGroupsForDomain(DomainInfo domain, int batchSize, CancellationToken ct)
{
try
{
return await BlahBlahActuallyGoGetGroupsForDomainHere(domain, batchSize, ct);
}
catch (Exception e)
{
return null;
}
}
var executeQueries = new List<Func<CancellationToken, Task<ICollection<Group>>>>();
domains.ForEach(domain =>
executeQueries.Add(async (ct) =>
await ExecuteQueryGroupsForDomain(domain, 123, ct)));
现在,如果我尝试替换
ForEach
使用 LINQ 的循环部分:var executeQueries = domains.Select(domain =>
async (ct) => await ExecuteQueryGroupsForDomain(domain, 123, ct));
它提示
Type arguments cannot be inferred by the usage
这让我相信我没有从 Select
返回任何东西,但我显然要返回 Func
我想。有没有更好的方法来创建
Func
列表?的,理想情况下避免显式转换?还有什么解释为什么编译器在 Select
时无法推断类型? 'd async 方法清楚地告诉它应该是什么类型?要清楚,我确实需要通过
CancellationToken
到Func
是因为它是与外部 token 不同的 token (具体来说,它是将外部 token 与另一个内部 token 联系起来的链接 token )。
最佳答案
问题在于选择的返回,因为编译器不清楚返回的类型是什么。所以,你需要明确返回的类型,这里有两种方法:
executeQueries = domains.Select(domain =>
new Func<CancellationToken, Task<ICollection<Group>>>(token =>
this.ExecuteQueryGroupsForDomain(domain, 123, token))).ToList();
executeQueries = domains
.Select<DomainInfo, Func<CancellationToken, Task<ICollection<Group>>>>(domain =>
ct => this.ExecuteQueryGroupsForDomain(domain, 123, ct)).ToList();
==================================================== =====================
编辑1:
编译器无法从 lambda 表达式推断类型,因为 lambda 只是匿名方法的简写,而不是类型。因此,您需要明确并指出方法的返回类型,如果返回是基委托(delegate)或其他委托(delegate)类型,如 Action、Func 等。查看 this其他答案,其中解释了基于 C# 4 规范的错误编译器。
如果您需要将原始代码转换为更具可读性的内容,我认为没有另一种更具可读性的方式。以下是可以编写代码的其他方式:
foreach (var domain in domains) {
executeQueries.Add(token => this.ExecuteQueryGroupsForDomain(domain, 123, token));
}
executeQueries.AddRange(domains
.Select(domain => (Func<CancellationToken, Task<ICollection<Group>>>) (token =>
this.ExecuteQueryGroupsForDomain(domain, 123, token))));
executeQueries =
(from domain in domains
select new Func<CancellationToken, Task<ICollection<Group>>>(token =>
this.ExecuteQueryGroupsForDomain(domain, 123, token))).ToList()
关于c# - 选择异步函数的更好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61585021/