When building a LambdaExpression at runtime, if I use a LambdaExpression as a parameter to a call expression (like when using Linq), then compile the main lambda, does the nested lambda also compile or does it need to?
The code functions the same if I use the LambdaExpression as a parameter to a method taking Func<T, T2>
or if I compile it and use a Expression.Constant
over the compiled Func
.
Not compiled:
var selectParam = Expression.Parameter(propType, "selectParam");
var selectExp = Expression.Call(typeof(System.Linq.Enumerable).GetMethods().First(a => a.Name == "Select" && /*Func<TSource,TResult>*/ a.GetParameters().Last().ParameterType.GenericTypeArguments.Length == 2).MakeGenericMethod(propType, typeof(int)),
whereExp,
Expression.Lambda(Expression.Property(selectParam, "Length"), selectParam));
Compiled:
var selectParam = Expression.Parameter(propType, "selectParam");
var selectExp = Expression.Call(typeof(System.Linq.Enumerable).GetMethods().First(a => a.Name == "Select" && /*Func<TSource,TResult>*/ a.GetParameters().Last().ParameterType.GenericTypeArguments.Length == 2).MakeGenericMethod(propType, typeof(int)),
whereExp,
Expression.Constant(Expression.Lambda(Expression.Property(selectParam, "Length"), selectParam).Compile())); //compile
The expressions I'm building are called millions of times in a loop so I'd like to know if compiling the outer lambda compiles the inner lambdas properly.
Since this isn't easy to explain, see my fiddle here.
I'm pretty sure they won't be compiled as the methods being called could want them as Expressions to parse them. In this case, is there a runtime performance gain to compile them when used like this?
Thinking at a higher level, When used in a standard way in a loop - is this optimized at all? Certainly they aren't compiled on every call when doing linq over an array or such?