Viewing the IL code generated from a compiled expr

2019-01-13 03:27发布

问题:

Is it possible to view the IL code generated when you call Compile() on an Expression tree? Consider this very simple example:

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;
    }
}

Now, the expression tree does what the last line of Main says. Compile the application, then open it in Reflector. You can see the IL code of p.Value = 5; that does the assignment. But the expression tree was made and compiled at runtime. Is it possible to view the resulting IL code from the compile?

回答1:

Yes! Use this tool:

http://blogs.msdn.com/b/haibo_luo/archive/2006/11/16/take-two-il-visualizer.aspx

This was incredibly useful when I was implementing and debugging Compile, as I'm sure you can imagine.



回答2:

Create a DynamicAssembly, then a DynamicModule, DynamicType and DynamicMethod. Make that method public and static and pass it to the method CompileTo() on the lambda. When you make the assembly flag it as Save. Then call the Save() method and pass a path. It will be written to disk. Pop it open in reflector.

Something like:

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");