显然,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;
}
}
}
(也许不完全是这样,但你明白了。)
现在的问题是,当我尝试使用MyClass
从ICSharpCode.Decompiler.Ast.AstBuilder
的程序集中以编程方式构建AST时,这些内部类不包含在AST中(其他一切都很好) 。我甚至可以在MyClass
' s TypeDecleration
的注释中看到这些生成的类:类型为Mono.Cecil.TypeDefinition
的注释在其NestedTypes
属性中正确列出了这些内部类(因此它们从程序集中正确加载但未添加到语法树中;另外,手动创建的内部类也被正确反编译)。
另请参阅我打开的这个ILSpy问题:https://github.com/icsharpcode/ILSpy/issues/686
我错过了一些明显的东西吗?我还使用GUI查看了来自ILSpy的程序集,并且有问题的代码被正确反编译(虽然不是内部类,而是重建了lambda)。
答案 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;