I have Expression<Action<T>>
where Action is call of function, but function result is not used. Let's consider the following code sample:
using System;
using System.Linq.Expressions;
namespace ConsoleApp
{
class Program
{
public class MyArg
{
public int Data { get; set; }
}
public class MyExecutor
{
public bool Executed { get; set; }
public int MyMethod(int simpleArg, MyArg complexArg)
{
int result = simpleArg + complexArg.Data;
this.Executed = true;
return result;
}
}
static void Main(string[] args)
{
Expression<Action<MyExecutor>> expr = t => t.MyMethod(2, new MyArg { Data = 3 });
var executor = new MyExecutor();
Action<MyExecutor> action = expr.Compile();
action(executor);
Console.WriteLine(executor.Executed); // true
}
}
}
There can lot of different actions, with different number of arguments. In all cases I have only such kind of expr
which always calls a function and that function always returns the same type, in my example above it is int
.
I need to have something like this:
static Expression<Func<MyExecutor, int>> ToExpressionOfFunc(Expression<Action<MyExecutor>> expr)
{
// TODO
throw new NotImplementedException();
}
to be able to make a call like this:
Expression<Func<MyExecutor, int>> funcExpr = ToExpressionOfFunc(expr);
Func<MyExecutor, int> func = funcExpr.Compile();
int result = func(executor);
Console.WriteLine(result); // should print 5
I have a feeling that this should be possible but have no ideas where to start from. I see in debug that there is an expr.Body.Method with desired ReturnType of Int32, but not clear how to extract it properly to the new Expression<Func>
.
It's simple, just create a new Expression<Func<MyExecutor, int>>
using the body and parameters from the existing expression:
static Expression<Func<MyExecutor, int>> ToExpressionOfFunc(Expression<Action<MyExecutor>> expr)
{
return Expression.Lambda<Func<MyExecutor, int>>(expr.Body, expr.Parameters);
}
Note that this throws an exception if expr
is not of return type int
.