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

Pau*_*ith 4 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);
Run Code Online (Sandbox Code Playgroud)

问题是,这迫使我为每个不同的参数值集缓存不同的委托实例。这看起来有点浪费;Dynamic LINQ 的所有开销都在解析和编译中;一旦创建,委托的性能就接近于直接编码的 lambda。有没有什么方法可以将参数移到表达式之外,以便我可以在调用它时(而不是在创建它时)将不同的值传递给公共缓存委托

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

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

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

谢谢!

Mar*_*ell 5

这里有一个技巧,我以前用过;您执行类似 an 的操作Expression<Func<object[], object>>,并将按索引获取和转换嵌入表达式中。然后您就可以拥有尽可能多的参数、单个签名和合理的性能。然而,它确实使编写 lambda 变得有点棘手。

我没有这个“手头”的旧代码,但如果我需要对其进行逆向工程,我只需编写如下所示的典型代码,然后在反射器中查看它使用的内容:

Expression<Func<object[], object>> func = arr => ((string)arr[0]) + (int)arr[1];
Run Code Online (Sandbox Code Playgroud)

(特别是要注意索引器的使用、输入的转换以及输出的转换