【问题标题】:Viewing the IL code generated from a compiled expression查看从编译表达式生成的 IL 代码
【发布时间】:2011-06-13 10:47:22
【问题描述】:

是否可以查看在表达式树上调用 Compile() 时生成的 IL 代码?考虑这个非常简单的例子:

class Program
{
    public int Value { get; set; }

    static void Main(string[] args)
    {
        var param = Expression.Parameter(typeof(Program));
        var con = Expression.Constant(5);
        var prop = Expression.Property(param, typeof(Program).GetProperty("Value"));
        var assign = Expression.Assign(prop, con);
        Action<Program> lambda = Expression.Lambda<Action<Program>>(assign, param).Compile();

        Program p = new Program();
        lambda(p);



        //p.Value = 5;
    }
}

现在,表达式树执行Main 的最后一行所说的。编译应用程序,然后在 Reflector 中打开它。您可以看到执行分配的p.Value = 5; 的 IL 代码。但是表达式树是在运行时创建和编译的。是否可以从编译中查看生成的 IL 代码?

【问题讨论】:

  • 您是否只希望 等效 IL 用于您正在正在执行的操作(即设置属性)?或者您对Expression 输出有什么特别感兴趣的内容?
  • 没有具体内容。我喜欢不时查看 IL 代码。但是使用表达式,您可以创建一个在已编译程序集中不获取任何 IL 的方法。用于创建该表达式树的 IL 存在,但不是表达式树本身的编译结果。那有意义吗?这只是一种好奇心,并没有我能看到的任何实际用途。
  • 您尝试过出色的 LinqPad 工具吗? linqpad.net 有了它,您可以将生成的代码显示为 MSIL 并快速试验几乎任何东西...

标签: c# expression-trees il .net-reflector


【解决方案1】:

是的!使用这个工具:

https://github.com/drewnoakes/il-visualizer

这在我实现和调试 Compile 时非常有用,我相信您可以想象到。

【讨论】:

  • 埃里克,如果你有时间,你能把这个充实成一个更实质性的答案吗?在 Stack Overflow 上不鼓励仅链接答案。
  • 可惜不能编译,有二进制版本吗?
  • @casperOne:我鼓励你这样做。我没有什么要补充的。
  • @JeroenvanLangen:我一点也不知道。我建议您向其作者提出您的问题。
  • @EricLippert:Tyvm 对于您的反应,我通过将其保存到组件中并使用反射器/ilspy 解决了这个问题。再次Tnx。
【解决方案2】:

创建一个 DynamicAssembly,然后是一个 DynamicModule、DynamicType 和 DynamicMethod。将该方法设为 public 和 static 并将其传递给 lambda 上的方法 CompileTo()。当您制作程序集时,将其标记为保存。然后调用 Save() 方法并传递一个路径。它将被写入磁盘。在反射器中弹出它。

类似:

var da = AppDomain.CurrentDomain.DefineDynamicAssembly(
    new AssemblyName("dyn"), // call it whatever you want
    AssemblyBuilderAccess.Save);

var dm = da.DefineDynamicModule("dyn_mod", "dyn.dll");
var dt = dm.DefineType("dyn_type");
var method = dt.DefineMethod(
    "Foo", 
    MethodAttributes.Public | MethodAttributes.Static);

lambda.CompileToMethod(method);
dt.CreateType();

da.Save("dyn.dll");

【讨论】:

  • 如果有人有兴趣从DefineMethod 方法中删除MethodAttributes.Static,我有一些研究我得到了stackoverflow.com/a/3993023/903505 的结论,CompileToMethod 仅适用于静态方法
【解决方案3】:

我在网上遇到的最棒的工具之一是 SharpLab.io 它可以执行多项任务,例如生成 IL、JIT 代码,或者可以进行验证。它还支持语法树。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-22
    • 1970-01-01
    • 1970-01-01
    • 2012-11-24
    相关资源
    最近更新 更多