0

I want to reuse Expression instances for another Expression building like in the code below. Is it safe? Are there any pitfalls with it?

using System.Linq.Expressions;

class Program
{
    static void Main()
    {
        ParameterExpression x = Expression.Parameter(typeof(int), "x");
        ParameterExpression y = Expression.Parameter(typeof(int), "y");
        // Reuse x and y parameter expressions
        BinaryExpression sum = Expression.Add(x, y);
        BinaryExpression mutiply = Expression.Multiply(x, y);

        // Reuse multiply and sum expressions
        BinaryExpression foo = Expression.Subtract(mutiply, sum); // xy - (x + y)

        Func<int, int, int> sumFunc = Expression.Lambda<Func<int, int, int>>(sum, x, y).Compile();
        Func<int, int, int> multiplyFunc = Expression.Lambda<Func<int, int, int>>(mutiply, x, y).Compile();
        Func<int, int, int> fooFunc = Expression.Lambda<Func<int, int, int>>(foo, x, y).Compile();
        
        Console.WriteLine(sumFunc(3, 2));
        Console.WriteLine(multiplyFunc(3, 2));
        Console.WriteLine(fooFunc(3, 2));
    }
}
1
  • The only potential issue is if you try to combine expressions (lambda bodies) that use the parameters in semantically different ways but what you are doing is fine for expressions designed to be combine, otherwise you need to do parameter replacement. Commented Feb 2, 2024 at 22:34

1 Answer 1

0

You can safely reuse expressions.

Expression trees are immutable, so you don't need to worry about whoever using sum modifying the LHS and RHS expressions, causing whoever is using multiply to also (unexpectedly) see the change. Of course, if you deliberately put something mutable in a node (e.g. a List<T>), something like the above could happen. But that isn't really Expression's problem.

Expression is a reference type, so the only difference that reusing vs not reusing is going to make, is that some tree nodes will have the same references to the child node. For example, in your code, object.ReferenceEquals(sum.Left, multiply.Left) would be true. If you didn't reuse x, it would be false. That said, it is very hard to imagine any use case of expression trees that depend on whether two nodes are the same reference. Most APIs that consume expression trees just look at the types of the nodes, and the values in them.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.