jk_*_*jk_ 31 c# lambda compilation abstract-syntax-tree
我想在C#中理解AST.我想知道,Compile()这个例子的确切方法是什么.
// Some code skipped
Expression<Func<string, int, int, string>> data = Expression.Lambda<Func<string, int, int, string>>(
Expression.Call(s, typeof(string).GetMethod(“Substring”, new Type[] { typeof(int), typeof(int) }), a, b),
s, a, b
);
Func<string, int, int, string> fun = data.Compile();
Run Code Online (Sandbox Code Playgroud)
为了防止误解,我理解Expression.Lambda和Expression.Call构建.我感兴趣的是Compile()方法.它以某种方式生成真正的MSIL?我能看到MSIL吗?
Eri*_*ert 50
我感兴趣的是
Compile()方法.它以某种方式生成真正的MSIL?
是.Compile方法在lambda body块上运行访问者,并为每个子表达式动态生成IL.
如果您有兴趣学习如何自己吐IL,请参阅如何使用Lightweight Codegen的"Hello World"示例.(我注意到,如果你处于部分受信任的应用程序域中必须使用Lightweight Codegen的不幸位置,那么在具有限制性跳过可见性的世界中,事情会变得有些奇怪; 如果您感兴趣,请参阅Shawn Farkas关于该主题的文章.)
我能看到MSIL吗?
是的,但你需要一个特殊的"可视化器".Compile()我在实现我的部分时用于调试的可视化工具可以在这里下载:
http://blogs.msdn.com/b/haibo_luo/archive/2005/10/25/484861.aspx
对此的答案现在已经过时了,因为现在有时会发生什么.
向IL编译表达式需要Reflection.Emit,它始终不可用,特别是AOT.因此,在这些情况下,不是编译到IL,而是将表达式"编译"为表示指令的对象列表.这些指令中的每一个都有一个Run方法可以使它执行适当的操作,处理一堆值,就像IL在堆栈上工作一样.Run然后可以将调用这些对象的方法作为委托返回.
通常运行这样的委托比运行IL慢,但它是唯一的选项,当编译到IL不可用时,编译步骤通常更快,所以编译+运行的总时间通常少于解释器而不是IL用于一次性表达.
出于这个原因,在.NET Core中,现在有一个重载,Compile它需要一个布尔请求的解释,即使编译为IL可用.
所有这些都构成了一种有趣的语言组合; 表达式本身是一种语言,程序集用C#编写,它可以编译成IL,解释的指令对象构成第四种语言.
| 归档时间: |
|
| 查看次数: |
17534 次 |
| 最近记录: |