tags:

views:

64

answers:

1

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 delegate 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!

+2  A: 

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)

Marc Gravell
Paul Smith