31

是否可以查看在表达式树上调用 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 代码?

4

3 回答 3

29

是的!使用这个工具:

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

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

于 2011-01-21T22:48:21.083 回答
24

创建一个 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");
于 2011-01-21T22:56:29.317 回答
0

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

于 2020-08-16T23:23:18.997 回答