Search code examples
c#expression-trees

Expression.New(..) - but I already have an object


Looking at expression trees in C# and was reading this article.

// Add the following directive to your file:
// using System.Linq.Expressions;  
public class SampleClass
{
    public int AddIntegers(int arg1, int arg2)
    {
        return arg1 + arg2;
    }
}

static public void TestCall()
{
    // This expression represents a call to an instance method that has two arguments.
    // The first argument is an expression that creates a new object of the specified type.
    Expression callExpr = Expression.Call(
        Expression.New(typeof(SampleClass)),
        typeof(SampleClass).GetMethod("AddIntegers", new Type[] { typeof(int), typeof(int) }),
        Expression.Constant(1),
        Expression.Constant(2)
        );

    // Print out the expression.
    Console.WriteLine(callExpr.ToString());

    // The following statement first creates an expression tree,
    // then compiles it, and then executes it.
    Console.WriteLine(Expression.Lambda<Func<int>>(callExpr).Compile()());

    // This code example produces the following output:
    //
    // new SampleClass().AddIntegers(1, 2)
    // 3
}

I want to do something almost identical to this, except I don't want to create a new instance of SampleClass - I already have an instance, I just want to invoke a method on it.

The code essentially does this:

new SampleClass().AddIntegers(1, 2)

...using expression trees; however, I want to do this:

sampleClassInstance.AddIntegers(1, 2)

Is this something I can do, or should I just stick with reflection for this?


Solution

  • You can do this:

    public class SampleClass
    {
        public int AddIntegers(int a, int b)
        {
            return a + b;
        }
    }
    
    var sampleClass = new SampleClass();
    Expression callExpr = Expression.Call(
        Expression.Constant(sampleClass),
        typeof(SampleClass).GetMethod("AddIntegers", new Type[] { typeof(int), typeof(int) }),
        Expression.Constant(1),
        Expression.Constant(2)
        );