如何优化LINQ表达式?
在使用 .NET 3.5 构建的项目中,我使用 LINQ 表达式在运行时动态生成代码。 LINQ 表达式使用 Compile 方法进行编译并存储以供以后用作 LINQ to 对象的谓词。
这些表达式有时非常复杂且难以调试。
下面是通过 Visual Studio 中的调试器可视化工具查看的表达式示例。
{请求 => (调用(workEnvelopeHead => (workEnvelopeHead.Method = value(Wombl.Scenarios.CannedResponses+<>c_DisplayClass58).pipeline), 请求.WorkEnvelope.Head) 并调用(body => 调用(值(Wombl.Scenarios.CannedResponses+<>c_DisplayClass78).isMatch, body.SingleOrDefault()),Convert(request.WorkEnvelope.Body.Any)))}
我希望能够像上面那样优化表达式,以便 value(Wombl.Scenarios.CannedResponses+<> c__DisplayClass58).pipeline
表达式被替换为变量值常量。
在这种特殊情况下,value(Wombl.Scenarios.CannedResponses+<>c__DisplayClass58).pipeline 是 lambda 中对父作用域中变量的引用。类似于:
var pipeline = "[My variable's value here]";
// My lambda expression here, which references pipeline
// Func<RequestType, bool> predicate = request => ........ workEnvelopeHead.Method == pipeline ..........
优化后的原始表达式应该如下所示:
{请求=> (调用(workEnvelopeHead => (workEnvelopeHead.Method = "[这里是我的变量值]", request.WorkEnvelope.Head) 和 Invoke(body => > Invoke(value(Wombl.Scenarios.CannedResponses+<>c__DisplayClass78).isMatch, body.SingleOrDefault()),Convert(request.WorkEnvelope.Body.Any)))}
如何在编译之前在运行时对 LINQ 表达式进行此类优化?
On a project built with .NET 3.5, I am using LINQ expressions to dynamically generate code at runtime. The LINQ expressions are compiled using the Compile method and stored for later use as predicates with LINQ to objects.
The expressions are sometimes quite complicated and difficult to debug.
Below is an example of an expression viewed through the debugger visualizer in Visual Studio.
{request
=> (Invoke(workEnvelopeHead
=> (workEnvelopeHead.Method = value(Wombl.Scenarios.CannedResponses+<>c_DisplayClass58).pipeline),
request.WorkEnvelope.Head)
And Invoke(body =>
Invoke(value(Wombl.Scenarios.CannedResponses+<>c_DisplayClass78).isMatch,
body.SingleOrDefault()),Convert(request.WorkEnvelope.Body.Any)))}
I would like to be able to optimize expressions like the above so that the value(Wombl.Scenarios.CannedResponses+<>c__DisplayClass58).pipeline
expression is replaced with a constant that is the variable's value.
In this particular case, value(Wombl.Scenarios.CannedResponses+<>c__DisplayClass58).pipeline
is a reference in the lambda to a variable in the parent scope. Something like:
var pipeline = "[My variable's value here]";
// My lambda expression here, which references pipeline
// Func<RequestType, bool> predicate = request => ........ workEnvelopeHead.Method == pipeline ..........
The original expression, optimized ought to look like:
{request => (Invoke(workEnvelopeHead =>
(workEnvelopeHead.Method = "[My variable's value here]",
request.WorkEnvelope.Head) And Invoke(body => > Invoke(value(Wombl.Scenarios.CannedResponses+<>c__DisplayClass78).isMatch,
body.SingleOrDefault()),Convert(request.WorkEnvelope.Body.Any)))}
How can I make such optimizations at runtime to the LINQ expression, before compiling?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
因此,我继续编写了一个表达式访问器,用实际值替换变量引用。毕竟这并不难做到。
用法:
该类:
它继承自 ExpressionVisitor,它来自此页面上的代码示例,因为在 .NET 3.0 中它是内部的。在 .NET 4.0 中,该类是公共的,但可能需要对该类进行一些更改。
So I went ahead and wrote an expression visitor that replaces the variable references with the actual value. It wasn't so hard to do after all.
Usage:
The class:
It inherits from ExpressionVisitor which came from the code samples on this page because in .NET 3.0 it is internal. In .NET 4.0 the class is public but might require some changes to this class.