c# – 使用嵌套的LambdaExpressions编译LambdaExpression时,它们是否也会编译?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 使用嵌套的LambdaExpressions编译LambdaExpression时,它们是否也会编译?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3974字,纯文字阅读大概需要6分钟。
内容图文
![c# – 使用嵌套的LambdaExpressions编译LambdaExpression时,它们是否也会编译?](/upload/InfoBanner/zyjiaocheng/797/7caec2796a6c4d31bbef22ae09ecdc1f.jpg)
在运行时构建LambdaExpression时,如果我使用LambdaExpression作为调用表达式的参数(比如使用Linq时),那么编译主lambda,嵌套的lambda是否也编译或者是否需要?
如果我将LambdaExpression用作采用Func< T,T2>的方法的参数,则代码的功能相同.或者如果我编译它并在编译的Func上使用Expression.Constant.
没编译:
var selectParam = Expression.Parameter(propType, "selectParam");
var selectExp = Expression.Call(typeof(System.Linq.Enumerable).GetMethods().First(a => a.Name == "Select" && /*Func<TSource,TResult>*/ a.GetParameters().Last().ParameterType.GenericTypeArguments.Length == 2).MakeGenericMethod(propType, typeof(int)),
whereExp,
Expression.Lambda(Expression.Property(selectParam, "Length"), selectParam));
编译:
var selectParam = Expression.Parameter(propType, "selectParam");
var selectExp = Expression.Call(typeof(System.Linq.Enumerable).GetMethods().First(a => a.Name == "Select" && /*Func<TSource,TResult>*/ a.GetParameters().Last().ParameterType.GenericTypeArguments.Length == 2).MakeGenericMethod(propType, typeof(int)),
whereExp,
Expression.Constant(Expression.Lambda(Expression.Property(selectParam, "Length"), selectParam).Compile())); //compile
我正在构建的表达式在循环中被称为数百万次,所以我想知道编译外部lambda是否正确编译了内部lambda.
由于这不容易解释,请看我的小提琴here.
我很确定它们不会被编译,因为被调用的方法可能希望它们作为表达式来解析它们.在这种情况下,如果像这样使用,是否有运行时性能增益来编译它们?
在更高层次上思考,当在循环中以标准方式使用时 – 这是否优化?当然,在对数组执行linq时,它们不会在每次调用时编译?
解决方法:
简短回答:是的,每个内部lambda都将被编译.
我略微修改了你的第一个方法(但它生成了相同的表达式):
private static Expression<Func<int>> ActuallyInnerAlsoCompile()
{
var strType = typeof(string);
var intType = typeof(int);
var enumearbleType = typeof(Enumerable);
var array = Expression.NewArrayInit(strType, Expression.Constant("test"), Expression.Constant("test2"));
var x = Expression.Parameter(strType, "whereParam");
var whereExp = Expression.Call(enumearbleType,
"Where",
new[] {strType},
array,
Expression.Lambda(Expression.NotEqual(Expression.PropertyOrField(x, "Length"), Expression.Constant(4)), x));
var selectExp = Expression.Call(enumearbleType,
"Select",
new[] {strType, intType},
whereExp,
Expression.Lambda(Expression.PropertyOrField(x, "Length"), x));
var firstOrDefault = Expression.Call(enumearbleType,
"FirstOrDefault",
new[] {intType},
selectExp);
return Expression.Lambda<Func<int>>(firstOrDefault);
}
现在您可以参考此answer并将表达式编译为新程序集:
var lambda = ActuallyInnerAlsoCompile();
var dynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(
new AssemblyName("dynamicAssembly"),
AssemblyBuilderAccess.Save);
var dm = dynamicAssembly.DefineDynamicModule("dynamicModule", "dynamic.dll");
var dt = dm.DefineType("dynamicType");
var m1 = dt.DefineMethod(
"dynamicMethod",
MethodAttributes.Public | MethodAttributes.Static);
lambda.CompileToMethod(m1);
dt.CreateType();
dynamicAssembly.Save("dynamic.dll");
如果你用一些IL工具(例如dotPeek)打开那个dynamic.dll,你会看到类似的东西:
// Decompiled with JetBrains decompiler
// Type: dynamicType
// Assembly: dynamicAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 94346EDD-3BCD-4EB8-BA4E-C25343918535
using System;
using System.Collections.Generic;
using System.Linq;
internal class dynamicType
{
public static int dynamicMethod()
{
return ((IEnumerable<string>) new string[2]
{
"test",
"test2"
}).Where<string>(new Func<string, bool>(dynamicType.\u003CExpressionCompilerImplementationDetails\u003E\u007B1\u007Dlambda_method)).Select<string, int>(new Func<string, int>(dynamicType.\u003CExpressionCompilerImplementationDetails\u003E\u007B2\u007Dlambda_method)).FirstOrDefault<int>();
}
private static bool \u003CExpressionCompilerImplementationDetails\u003E\u007B1\u007Dlambda_method(string whereParam)
{
return whereParam.Length != 4;
}
private static int \u003CExpressionCompilerImplementationDetails\u003E\u007B2\u007Dlambda_method(string whereParam)
{
return whereParam.Length;
}
}
或者(没有丑陋的unicode转义序列)
内容总结
以上是互联网集市为您收集整理的c# – 使用嵌套的LambdaExpressions编译LambdaExpression时,它们是否也会编译?全部内容,希望文章能够帮你解决c# – 使用嵌套的LambdaExpressions编译LambdaExpression时,它们是否也会编译?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。