预编译异常:委托 'Action' 不接受 1 个参数
Precompile Exception: Delegate 'Action' does not take 1 arguments
我正在尝试修复从 public 存储库克隆的一些代码。这是缺少 await
运算符的 async
方法:
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:
中遇到错误
Delegate 'Action' does not take 1 arguments
我发现了一些类似的讨论,但不幸的是 none 其中完全解决了 lambda 语法问题:
- Delegate System.Action does not take 1 arguments
- Delegate System.Action<dynamic,int> does not take `1' arguments
- Delegate Action does not take 3 arguments
似乎预编译器将输入解释为 Action
而它应该将其视为 Func
。但我认为语句 o => ...
可以指示两者之一。
我对 C# 不够熟悉,无法解决这个问题。有人可以帮忙吗?
如何告诉预编译器我要发送 Func
而不是 Action
?
嗯,编译错误的原因是 Task.Run
接受(非泛型)Action
,这是一个不接受任何参数的委托。
您已尝试使用接受参数 o
的 lambda 调用 Task.Run
,因此更改为此将消除错误:
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 强制到线程池上的 运行。
我正在尝试修复从 public 存储库克隆的一些代码。这是缺少 await
运算符的 async
方法:
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:
中遇到错误Delegate 'Action' does not take 1 arguments
我发现了一些类似的讨论,但不幸的是 none 其中完全解决了 lambda 语法问题:
- Delegate System.Action does not take 1 arguments
- Delegate System.Action<dynamic,int> does not take `1' arguments
- Delegate Action does not take 3 arguments
似乎预编译器将输入解释为 Action
而它应该将其视为 Func
。但我认为语句 o => ...
可以指示两者之一。
我对 C# 不够熟悉,无法解决这个问题。有人可以帮忙吗?
如何告诉预编译器我要发送 Func
而不是 Action
?
嗯,编译错误的原因是 Task.Run
接受(非泛型)Action
,这是一个不接受任何参数的委托。
您已尝试使用接受参数 o
的 lambda 调用 Task.Run
,因此更改为此将消除错误:
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 强制到线程池上的 运行。