首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >轻量级代码生成(LCG)死了吗?

轻量级代码生成(LCG)死了吗?
EN

Stack Overflow用户
提问于 2010-06-09 07:03:48
回答 4查看 2.7K关注 0票数 8

在LCG2.0-3.5框架中,当不需要任何类结构来支持轻量级方法时,.NET (也称为DynamicMethod类)是一种在运行时发出轻量级方法的好方法。

在CIL4.0中,表达式树现在支持语句和块,因此似乎提供了足够的功能来构建这种方法所需的几乎任何功能,并且可以以一种比直接发出.NET操作码更容易、更安全的方式来构建。(这句话来自于今天的实验,我们将一些最复杂的LCG代码转换为使用表达式树构建和编译。)

那么,有没有理由在新代码中使用LCG呢?它能做表达式树做不到的事情吗?或者它现在是一个“死”的功能部分?

EN

回答 4

Stack Overflow用户

发布于 2011-04-13 04:11:03

没有任何中间步骤,直接构建CIL是没有意义的。但是,使用您自己的中间语言并最终以IL为目标是完全可以的。表达式树等是不够的-它只是一种语言,而在实现DSL时,您需要许多不同的语义。

你可以很容易地发出不安全的代码(有很多ldftn和类似的代码),你可以发出尾部调用(不确定表达式是否可能),对虚拟方法的非虚拟调用,你可以高效地构造带有标签和跳转的大型状态自动机,等等。表达式树是如此有限,以至于我无法理解它们如何与原始的CIL进行比较。

票数 3
EN

Stack Overflow用户

发布于 2011-04-13 03:11:03

嗯,这个问题现在已经很老了,我正在等待tf get的完成……所以我自己来回答。

是的,LCG在大多数情况下都是死的。

我们过去经常使用LCG,现在已经全部转换为使用表达式树。它们更容易构建,代码更容易维护和调试,当你在开发过程中出错时,错误消息通常比“操作可能会破坏运行时的稳定性”更具信息性。

但是,也许最重要的是,表达式树是可组合的,这是Reflection.Emit所不能做到的。这意味着用于运行时代码生成的组件的架构可以更加模块化,甚至允许插件扩展代码生成框架。

我发现Reflection.Emit支持的一件事是在表达式树中不直接支持的是设置.initonly字段。然而,这可以通过使用一个小助手类并在表达式树中调用它来实现,例如,我使用的是如下所示:

代码语言:javascript
复制
internal static class FieldHelper
{
    public static TTarget AssignInitOnlyField<TTarget, TField>(
        TTarget target, string fieldName, TField value)
    {
        var field = target.GetType().GetField(
            fieldName, 
            BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
        var boxed = (object)target; // required for value type support
        field.SetValue(boxed, value);
        return (TTarget)boxed;
    }
}

值得一提的是,使用表达式树而不是LCG的一个缺点是,表达式树的构建和编译肯定比直接发出原始操作码要慢。假设您正在缓存已编译的方法,这不太可能是一个重要的问题,但这仍然是迫使您使用LCG的一个原因。

票数 1
EN

Stack Overflow用户

发布于 2014-11-20 04:21:25

对于大多数运行时生成的代码来说,表达式树无疑是一种方法。但是,您应该清楚地认识到,它是有限的,并且不能让您访问MSIL语言的全部功能。因此,LGC和ILGenerator肯定会留下来完成要求更高的任务。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3001986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档