Просмотр кода IL, сгенерированного из скомпилированного выражения - PullRequest
30 голосов
/ 22 января 2011

Можно ли просмотреть код IL, сгенерированный при вызове Compile () в дереве выражений? Рассмотрим этот очень простой пример:

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. Вы можете увидеть код IL p.Value = 5;, который выполняет назначение. Но дерево выражений было создано и скомпилировано во время выполнения. Можно ли просмотреть полученный код IL из компиляции?

Ответы [ 2 ]

29 голосов
/ 22 января 2011

Да! Используйте этот инструмент:

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

Это было невероятно полезно, когда я внедрял и отлаживал компиляцию, как я уверен, вы можете себе представить.

24 голосов
/ 22 января 2011

Создайте DynamicAssembly, затем DynamicModule, DynamicType и DynamicMethod. Сделайте этот метод общедоступным и статическим и передайте его методу 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");
...