-2

I would like to generate a Expression that represents this lambda expression:

x => this.SomeMethod(y, x)

I know this is basic, but I'm new to Expressions.

Please notice:

  • I want to generate the Expression using Expression static methods like Expression.Call, Expression.Lambda...
  • The code is in a Portable Class Library (PCL), if that matters!

Edit

My current code looks like this:

public class Test
{
    public static void Main()
    {
        // as expression tree
        var parameter1 = Expression.Parameter(typeof(int), "p1");
        var parameter2 = Expression.Parameter(typeof(int), "p2");

        var instance = new SampleClass();   // I'm sure I need this, but how to inject it into Expression.Call?

        var methodInfo = typeof(SampleClass).GetMethod("SumLargerThan5",
        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
        var lambdaExpression = Expression.Lambda(
        Expression.Call(methodInfo, new[] { parameter1, parameter2 }),
        parameter1, parameter2);

        // testing 
        var compiledExpr2 = (Action<int, int>)lambdaExpression.Compile();
        compiledExpr2(2, 2);
        compiledExpr2(4, 2);
    }

    public class SampleClass
    {
        private void SampleMethod(int x, int y)
        {
             Console.WriteLine(this);
        }
    }
}
halfer
  • 19,824
  • 17
  • 99
  • 186
SuperJMN
  • 13,110
  • 16
  • 86
  • 185
  • 1
    That's nice! Is there a question in here? Does [this](http://stackoverflow.com/questions/1310752/lambda-to-expression-tree-conversion) help? – CodeCaster Dec 28 '14 at 13:11
  • The lambda receives one argument (x), the inner method requires two (x and y). Where does that argument come from? – John Dec 28 '14 at 13:25

1 Answers1

0

This example would give you an expression of the form you were asking. (one input param calling a method with two input params)

Both the Expression tree variant and the inline definition example can be found below

public class Test
{
    public static void TestMain()
    {
        // defined inline
        var expr = (Expression<Func<int, bool>>)(x => SumLargerThan5(x, 3));

        // testing 
        var compiledExpr1 = expr.Compile();
        bool b1 = compiledExpr1(2);
        bool b2 = compiledExpr1(4);

        // as expression tree
        var parameterExpr = Expression.Parameter(typeof(int));
        var methodInfo = typeof(Test).GetMethod("SumLargerThan5", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
        var lambdaExpression = Expression.Lambda(
            Expression.Call(methodInfo, parameterExpr, Expression.Constant(3)), 
            parameterExpr);

        // testing 
        var compiledExpr2 = (Func<int, bool>)lambdaExpression.Compile();
        bool b3 = compiledExpr2(2);
        bool b4 = compiledExpr2(4);
    }

    static bool SumLargerThan5(int x, int y)
    {
        return (x + y) > 5;
    }
}

If you're talking about an instance method:

public class Test2
{
    public static void Main2()
    {
        // as expression tree
        var parameter1 = Expression.Parameter(typeof(int), "p1");
        var parameter2 = Expression.Parameter(typeof(int), "p2");

        var instance = new SampleClass();   // I'm sure I need this, but how to inject it into Expression.Call?

        var methodInfo = typeof(SampleClass).GetMethod("SampleMethod",
        System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
        var lambdaExpression = Expression.Lambda(
        Expression.Call(Expression.Constant(instance), methodInfo, new[] { parameter1, parameter2 }),
        parameter1, parameter2);

        // testing 
        var compiledExpr2 = (Action<int, int>)lambdaExpression.Compile();
        compiledExpr2(2, 2);
        compiledExpr2(4, 2);
    }

    public class SampleClass
    {
        public void SampleMethod(int x, int y)
        {
            Console.WriteLine(this);
        }
    }
}
John
  • 3,627
  • 1
  • 12
  • 13
  • Thanks, but my objective is to create it using methods from the Expression static class like Expression.Lambda(Expression.Call(...)...). The types are known only at run time. – SuperJMN Dec 28 '14 at 13:39
  • OK, @codemonkey, it works nice in your example! but not in my code because the "SumLargerThan5" method is not static, it's an instance method. How could I use the Expression.Call to specify the instance in which the expression should call? Thanks! – SuperJMN Dec 28 '14 at 15:00
  • 1
    Added an example for the instance method case – John Dec 28 '14 at 15:08
  • I've just updated my question to include a modified version of your code that is very similar to what I have in my real project. If you run it, you will see that the Expression.Call line will throw an exception. I don't know how to make it work :( – SuperJMN Dec 28 '14 at 15:09