语法树中使用ICSharpCode Decompiler缺少Lambda表达式的嵌套类

时间:2016-03-21 23:21:36

标签: .net decompiling icsharpcode ilspy

显然,ICSharpCode反编译器不会以某种方式反编译由C#编译器为lambda表达式创建的内部类。请考虑以下示例:

在某些情况下,C#中的lambda表达式将使用包含lambda体的方法编译到内部类中。例如。像这样的C#代码:

class MyClass
{
    public void MyMethod()
    {
        Parallel.For(0, 10, i =>
        {
            ... = 3 * i;
        })
    }
}

将导致编译器添加如下所示的内部类:

class MyClass
{
    public void MyMethod()
    ...

    public class c__DisplayClass2()
    {
        public int i;

        public void b__0()
        {
            ... = 3 * i;
        }
    }
}

(也许不完全是这样,但你明白了。)

现在的问题是,当我尝试使用MyClassICSharpCode.Decompiler.Ast.AstBuilder的程序集中以编程方式构建AST时,这些内部类不包含在AST中(其他一切都很好) 。我甚至可以在MyClass' s TypeDecleration的注释中看到这些生成的类:类型为Mono.Cecil.TypeDefinition的注释在其NestedTypes属性中正确列出了这些内部类(因此它们从程序集中正确加载但未添加到语法树中;另外,手动创建的内部类也被正确反编译)。

另请参阅我打开的这个ILSpy问题:https://github.com/icsharpcode/ILSpy/issues/686

我错过了一些明显的东西吗?我还使用GUI查看了来自ILSpy的程序集,并且有问题的代码被正确反编译(虽然不是内部类,而是重建了lambda)。

1 个答案:

答案 0 :(得分:0)

我发现了问题:在使用语法树之前,您需要运行astBuilder.RunTransformations();,这也将重新创建委托。

在我这样做之前:

var assembly = AssemblyDefinition.ReadAssembly(typeof(Program).Assembly.Location);
var decompilerContext = new DecompilerContext(assembly.MainModule);
var astBuilder = new AstBuilder(decompilerContext);
astBuilder.AddAssembly(assembly);

var syntaxTree = astBuilder.SyntaxTree;

但是要正确初始化语法树,您需要:

var assembly = AssemblyDefinition.ReadAssembly(typeof(Program).Assembly.Location);
var decompilerContext = new DecompilerContext(assembly.MainModule);
var astBuilder = new AstBuilder(decompilerContext);
astBuilder.AddAssembly(assembly);
astBuilder.RunTransformations(); // This is new.

var syntaxTree = astBuilder.SyntaxTree;