Cache delegate of compiled Dynamic Linq Func<> *without* params?
I'm using the Dynamic.ParseLambda method from the Dynamic LINQ library to create expressions, compile each to a Func<>, and cache each in a dictionary:
// parse some dynamic expression using this ParseLambda sig:
Expression<Func<TArgument,TResult>> funcExpr =
System.Linq.Dynamic.ParseLambda<TArgument, TResult>(
expressionString, // string for dyn lambda expression
parameters); // object[] params
// then compile & cache the output of this as a delegate:
Func<TArgument,TResult> func = funcExpr.Compile(); //<-cache this
// then to execute, use:
return func(entityInstance);
The problem is, this forces me to cache a different delegate instance for every distinct set of parameter values. This seems kind of wasteful; all the overhead with Dynamic LINQ is in the parsing and compilation; once created, the delegates are near directly coded lambdas in performance. Is there any way to move the params outside of the expression, so I can pass different values to a common cached de开发者_运维技巧legate in when I call it (instead of when I'm creating it)?
// e.g. with params...
return func(entityInstance,parameters);
// or if params are the issue, multiple signatures are ok:
return func(entityInstance, intValue, stringValue);
I don't see any parameter-free .ParseLambda or .Compile signatures in System.Linq.Dynamic, so my hopes aren't high. Anyone know of a quick way to achieve this?
Thanks!
There is a trick here, that I have used before; you do something like an Expression<Func<object[], object>>
, and embed the fetch-by-index and casting inside the expression. Then you have as many parameters as you could want, a single signature, and reasonable performance. It does, however, make writing the lambda a bit tricker.
I don't have my old code for this "to hand", but if I needed to reverse engineer it, I would simply write something typical like the following, and then look in reflector to see what it used:
Expression<Func<object[], object>> func = arr => ((string)arr[0]) + (int)arr[1];
(in particular, paying attention to the indexer usage, the casting from inputs, and the casting to output)
精彩评论