首页 > 解决方案 > 预编译异常:委托“操作”不接受 1 个参数

问题描述

我正在尝试修复一些从公共仓库克隆的代码。这是一种async缺少await运算符的方法:

public async Task<IEnumerable<JsonPatchOperation>> GetRemoveAllRelationsOperations(IBatchMigrationContext batchContext, WorkItem targetWorkItem)
{
  return targetWorkItem.Relations?.Select((r, index) => MigrationHelpers.GetRelationRemoveOperation(index));
}

我正在尝试这个:

public async Task<IEnumerable<JsonPatchOperation>> GetRemoveAllRelationsOperations(IBatchMigrationContext batchContext, WorkItem targetWorkItem)
{
  return await Task.Run(o => targetWorkItem.Relations?.Select((r, index) => MigrationHelpers.GetRelationRemoveOperation(index)));
}

...但我在 IDE 中遇到错误:

委托“行动”不接受 1 个参数

我发现了一些类似的讨论,但不幸的是,它们都没有完全解决 lambda 语法:

似乎预编译器将输入解释为Action应该将其视为 a 的时间Func。但我认为该声明o => ...可以表明两者之一。

我对 C# 不够熟悉,无法解决这个问题。有人可以帮忙吗?

如何告诉预编译器我要发送 aFunc而不是 a Action

标签: c#async-awaitactionfunc

解决方案


好吧,编译错误的原因是它Task.Run接受一个 (non-generic) Action,它是一个不接受任何参数的委托。

您尝试Task.Run使用接受参数的 lambda 进行调用o,因此更改为 this 将消除错误:

Task.Run(() =>

括号()表示 lambda 表达式中没有参数。

话虽如此,包装一个同步函数Task.Run是一种反模式。

如果您的方法是完全同步的,则理想情况下应该这样公开它:

public IEnumerable<JsonPatchOperation> GetRemoveAllRelationsOperations(IBatchMigrationContext batchContext, WorkItem targetWorkItem)
{
    return targetWorkItem.Relations?
        .Select((r, index) => MigrationHelpers.GetRelationRemoveOperation(index));
}

如果您无法更改签名,例如,如果您正在实现一个接口,那么请Task.FromResult改用:

public async Task<IEnumerable<JsonPatchOperation>> GetRemoveAllRelationsOperations(IBatchMigrationContext batchContext, WorkItem targetWorkItem)
{
    return Task.FromResult(targetWorkItem.Relations?
        .Select((r, index) => MigrationHelpers.GetRelationRemoveOperation(index)));
}

这只是将同步结果包装在一个Task对象中,而不是强制 lambda 在线程池上运行。


推荐阅读