已编译的Dynamic Linq Func<>的缓存委托*没有*参数?

时间:2010-07-26 20:46:48

标签: c# linq dynamic

我正在使用Dynamic LINQ库中的Dynamic.ParseLambda方法创建表达式,将每个表达式编译为Func<>,并将每个表达式缓存在字典中:

// 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);

问题是,这迫使我为每个不同的参数值缓存一个不同的委托实例。这似乎有点浪费; Dynamic LINQ的所有开销都在解析和编译中;一旦创建,代表就会在性能上接近直接编码的lambdas。有没有办法将表达式移动到表达式之外,所以当我调用它时,我可以将不同的值传递给公共缓存的委托(而不是在我创建它时)?

// e.g. with params...
return func(entityInstance,parameters);

// or if params are the issue, multiple signatures are ok:
return func(entityInstance, intValue, stringValue);

我在System.Linq.Dynamic中没有看到任何无参数的.ParseLambda或.Compile签名,所以我的希望并不高。有人知道快速实现这个目标吗?

谢谢!

1 个答案:

答案 0 :(得分:3)

这里有一个技巧,我以前用过;你执行类似Expression<Func<object[], object>>的操作,并嵌入fetch-by-index并在内部表达式。然后,您可以拥有任意数量的参数,单个签名和合理的性能。然而,确实会让lambda写得有点过时。

我手边没有旧代码,但是如果我需要对其进行反向工程,我会简单地编写一些典型的代码,然后查看反射器以查看它的用途:

Expression<Func<object[], object>> func = arr => ((string)arr[0]) + (int)arr[1];

(特别注意索引器用法,从输入转换,转换到输出