这在 C# 中可能吗?以下代码会产生编译器错误。
HashSet<Task<(string Value, int ToNodeId)>> regionTasks =
new HashSet<Task<(string Value, int ToNodeId)>>();
foreach (Connection connection in Connections[RegionName])
{
regionTasks.Add(async () =>
{
string value = await connection.GetValueAsync(Key);
return (value, connection.ToNode.Id);
}());
}
C# 编译器抱怨,“错误 CS0149:需要方法名称。”它无法推断 lambda 方法的返回类型。
请注意我在 lambda 块关闭 {} 后立即通过 () 调用 lambda 方法的技术。这确保了Task
被返回,而不是Func
.
VB.NET 编译器理解此语法。我惊讶地发现 VB.NET 编译器胜过 C# 编译器的示例。看我的VB 胜过 C# 的异步 Lambda 编译器错误完整故事的博客文章。
Dim regionTasks = New HashSet(Of Task(Of (Value As String, ToNodeId As Integer)))
For Each connection In Connections(RegionName)
regionTasks.Add(Async Function()
Dim value = Await connection.GetValueAsync(Key)
Return (value, connection.ToNode.Id)
End Function())
Next
VB.NET 编译器理解End Function()
技术。它正确推断 lambda 方法的返回类型是Function() As Task(Of (Value As String, ToNodeId As Integer))
因此调用它会返回一个Task(Of (Value As String, ToNodeId As Integer))
。这可分配给regionTasks
多变的。
C# 要求我将 lambda 方法的返回值转换为Func
,这会产生极其难以辨认的代码。
regionTasks.Add(((Func<Task<(string Values, int ToNodeId)>>)(async () =>
{
string value = await connection.GetValueAsync(Key);
return (value, connection.ToNode.Id);
}))());
糟糕的。括号太多了!我在 C# 中能做的最好的事情就是显式声明一个Func
,然后立即调用它。
Func<Task<(string Value, int ToNodeId)>> getValueAndToNodeIdAsync = async () =>
{
string value = await connection.GetValueAsync(Key);
return (value, connection.ToNode.Id);
};
regionTasks.Add(getValueAndToNodeIdAsync());
有没有人找到更优雅的解决方案?