4

I'm stuck on a lambda with a single int parameter and a bool return value:

Expression<Func<int, bool>> myFunc = x => x == 5;

First, I tried this that returns a new Func that I can't make sense of; I was expecting a true boolean value:

var boolResult = Expression.Lambda(myFunc).Compile().DynamicInvoke(5);

Then I tried to explictly set the function parameters and return type instead:

var param = Expression.Parameter(typeof(int), "x");
var fn = Expression.Lambda<Func<int, bool>> (myFunc, param).Compile();

, but this throws an error:

System.ArgumentException : Expression of type 'System.Func`2[System.Int32,System.Boolean]' cannot be used for return type 'System.Boolean'

Which is weird, but I tried to convert the expression:

var fn = Expression.Lambda<Func<int, bool>> (
    Expression.Convert(myFunc,
    typeof(Func<int, bool>))
    , param).Compile();
var boolResult = fn.Invoke(5);

, this however did not help and gives the same error:

System.ArgumentException : Expression of type 'System.Func`2[System.Int32,System.Boolean]' cannot be used for return type 'System.Boolean'

Any idea of what I'm doing wrong here?

  • Where do you want to go with the Expression? For the function itself `Func myFunc = x => x == 5;` will do. See [here](http://stackoverflow.com/questions/793571/why-would-you-use-expressionfunct-rather-than-funct) includng the comments! – TaW Jun 12 '16 at 09:50
  • 1
    @TaW I'm getting the Expression from another library that I have no control of, so that's sadly not an option for me. –  Jun 12 '16 at 09:54

1 Answers1

2

The error in your dynamic invocation code is the way in which you construct your lambda. When you pass myFunc as expression, you get a lambda that returns Func<int,bool>.

If you want to make a new LambdaExpression that takes int and return bool, you could harvest Body and Parameters of your myFunc object, like this:

var b = Expression.Lambda(myFunc.Body, myFunc.Parameters).Compile().DynamicInvoke(5);

or, since myFunc is already a LambdaExpression, you could compile it directly:

var c = myFunc.Compile().DynamicInvoke(6);

Demo.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • And in case `myFunc` is strongly typed (as in the question `Expression>`), there is no need for `DynamicInvoke` in the last example. You could just do `var c = myFunc.Compile()(6);`. – Jeppe Stig Nielsen Nov 16 '20 at 12:43