C# 如何在不添加无法访问的代码的情况下编译此异步lambda?
我有一个方法:C# 如何在不添加无法访问的代码的情况下编译此异步lambda?,c#,lambda,async-await,c#-5.0,C#,Lambda,Async Await,C# 5.0,我有一个方法: void MyMethod<T>(params Func<T>[] funcs) { } 它起作用了!但是如果我想让第三个lambda抛出一个异常呢 MyMethod(async () => 1, async () => 2, async () => { throw new Exception(); }); 上面的代码没有编译,它给出了两个相同的错误: CS0201只能将赋值、调用、递增、递减和新对象表达式用作语句 我不确定它为什么会
void MyMethod<T>(params Func<T>[] funcs) { }
它起作用了!但是如果我想让第三个lambda抛出一个异常呢
MyMethod(async () => 1, async () => 2, async () => { throw new Exception(); });
上面的代码没有编译,它给出了两个相同的错误:
CS0201只能将赋值、调用、递增、递减和新对象表达式用作语句
我不确定它为什么会出现此错误,但我理解它为什么无法编译-前两个lambda是Func
,而最后一个是Func
。我希望它会给我一个更好的编译错误,但让我们把这个问题放在一边
如何获得要编译的代码?我可能必须告诉编译器我希望为第三个异步lambda生成什么类型的任务。我发现的一种方法是在throw
语句之后指定return
语句:
MyMethod(async () => 1, async () => 2, async () => { throw new Exception(); return 3; });
除了丑陋和混乱之外,它还会生成一个编译器警告:
CS0162检测到无法访问的代码
我如何让编译器高兴?如何避免不可访问的代码只是为了使其可编译?是否有其他方法指定异步lambda返回的任务类型?
另外,为什么在上面的示例中会出现CS0201错误?问题是编译器推断出
T
是任务,因为最后一个lambda没有返回类型
因此,它尝试将第一个lambda解析为没有返回值,这意味着它们必须作为语句而不是表达式有效。由于1
作为语句无效,您可能会遇到这个听起来奇怪的错误
要使代码编译,请显式传递泛型类型参数:
MyMethod<Task<int>>(async () => 1, async () => 2, async () => { throw new Exception(); });
MyMethod(async()=>1,async()=>2,async()=>{抛出新异常();});
第一个示例中的lambda不是Func
(如果没有上下文,它将是Action
),但它是该委托的有效lambda。因为它对您想要的委托有效,所以只需将其强制转换为:
MyMethod(async () => 1,
async () => 2,
(Func<Task<int>>)(async () => { throw new Exception(); }));
MyMethod(异步()=>1,
异步()=>2,
(Func)(异步()=>{throw new Exception();}));
既然您没有使用await
,那么首先为什么要使用异步lambda?@Servy:实际代码使用的是awaits。在第三个lambda中甚至有一个wait抛出异常。这是代码的精简版本。然后提供一个实际代表您实际代码的示例。提供async关键字不会使您的代码异步。我无法删除async
,因为实际代码在lambdas中使用waits。在第三个lambda中甚至有一个wait抛出异常。这是一个精简版的代码。即使是这样的示例,删除async
也会改变语义。我错了;这不是编译器错误。我添加了一个完整的解释。@SLaks:谢谢。简单的解决方案!不完全是,;如果这就是问题所在,他会得到一个无效的转换错误。因为这个推论,真正的问题在另一个lambda中。
MyMethod(async () => 1,
async () => 2,
(Func<Task<int>>)(async () => { throw new Exception(); }));