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));
}
}
You can safely reuse expressions.
Expression trees are immutable, so you don't need to worry about whoever using
summodifying the LHS and RHS expressions, causing whoever is usingmultiplyto also (unexpectedly) see the change. Of course, if you deliberately put something mutable in a node (e.g. aList<T>), something like the above could happen. But that isn't reallyExpression's problem.Expressionis 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 reusex, 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.