GeirGrusom
GeirGrusom

Reputation: 1019

Ignore return type from a Expression.Call

When an operation invokes an Expression.Call, it will throw an error stating that 'System.Boolean' cannot be converted to 'System.Void'

More specifically: I am implementing a 'wait' keyword which will simply call WaitOne() on a specified EventWaitHandle, and I am not interested in the return type, as it is supposed to wait indefinitely.

I have tried Expression.Convert(expression, typeof(void)), but it didn't really do anything interesting.

edit: I found one solution: put the expression in a block. Not sure why it has any effect.

Upvotes: 0

Views: 561

Answers (1)

Chris Chilvers
Chris Chilvers

Reputation: 6479

From the description it sounds like you were trying to create an Expression<Action>. However, the WaitOne method has the signature bool WaitOne() thus the resulting expression was trying to return a bool.

By wrapping the expression in a block you created a small thunk method that has no return value (void).


E.g. given the following code:

bool WaitOne() { return true; }
Action a = WaitOne;

The compiler cannot directly create a delegate of type Action for WaitOne because that would unbalance the stack; ie. the return value from WaitOne needs to be removed from the stack.

So to help you the compiler silently creates a method, thus what is actually compiled is similar to:

bool WaitOne() { return true; }
void k_CompilerGenerated() { WaitOne(); }
Action a = k_CompilerGenerated;

When building the expression yourself you don't have the luxury of the compiler doing this for you. So in essence, when you created the block, you manually did this same step that the compiler would normally perform.

Upvotes: 1

Related Questions