C# 忽略表达式的返回类型。调用

C# 忽略表达式的返回类型。调用,c#,.net,linq,expression,C#,.net,Linq,Expression,当操作调用Expression.Call时,它将抛出一个错误,指出“System.Boolean”无法转换为“System.Void” 更具体地说: 我正在实现一个'wait'关键字,它将对指定的EventWaitHandle调用WaitOne(),我对返回类型不感兴趣,因为它应该无限期地等待 我试过Expression.Convert(Expression,typeof(void)),但它并没有做任何有趣的事情 编辑:我找到了一个解决方案:将表达式放入块中。不确定它为什么会有任何效果。从描述中

当操作调用Expression.Call时,它将抛出一个错误,指出“System.Boolean”无法转换为“System.Void”

更具体地说: 我正在实现一个'wait'关键字,它将对指定的EventWaitHandle调用WaitOne(),我对返回类型不感兴趣,因为它应该无限期地等待

我试过Expression.Convert(Expression,typeof(void)),但它并没有做任何有趣的事情


编辑:我找到了一个解决方案:将表达式放入块中。不确定它为什么会有任何效果。

从描述中可以看出,您似乎试图创建一个
表达式。
但是,
WaitOne
方法具有签名
bool WaitOne()
,因此结果表达式试图返回
bool

通过将表达式包装在块中,您创建了一个没有返回值的小thunk方法(
void


例如,给定以下代码:

bool WaitOne() { return true; }
Action a = WaitOne;
编译器无法直接为
WaitOne
创建类型为
Action
的委托,因为这会使堆栈失衡;即,
WaitOne
的返回值需要从堆栈中删除

因此,为了帮助您,编译器以静默方式创建了一个方法,因此实际编译的内容类似于:

bool WaitOne() { return true; }
void k_CompilerGenerated() { WaitOne(); }
Action a = k_CompilerGenerated;
当您自己构建表达式时,编译器不会为您这样做。因此,本质上,当您创建块时,您手动执行了编译器通常执行的相同步骤