如何在x =>的代码中创建表达式树this.SomeMethod(y,x)?

时间:2014-12-28 13:11:09

标签: c# linq expression

我想生成一个代表这个lambda表达式的Expression:

x => this.SomeMethod(y, x)

我知道这是基本的,但我是Expressions的新手。

请注意:

  • 我想使用表达式静态方法生成Expression,如Expression.Call,Expression.Lambda ...
  • 如果重要的话,代码在可移植类库(PCL)中!

修改

我目前的代码如下:

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);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

此示例将为您提供您要求的表单的表达式。 (一个输入参数调用一个带有两个输入参数的方法)

表达式树变体和内联定义示例都可以在

下面找到
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;
    }
}

如果您正在谈论实例方法:

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);
        }
    }
}