【发布时间】:2019-02-19 01:50:18
【问题描述】:
我正在使用 AssemblyBuilder 创建一个复杂的类,我稍后会从中创建对象。然而,如何真正构建这个类存在不确定性。那么有没有办法把这个动态创建的类写到一个cs文件中进行检查呢?
我可以将 dll 文件写入磁盘,但我需要 cs 文件。
【问题讨论】:
标签: c# .net dynamic assemblybuilder
我正在使用 AssemblyBuilder 创建一个复杂的类,我稍后会从中创建对象。然而,如何真正构建这个类存在不确定性。那么有没有办法把这个动态创建的类写到一个cs文件中进行检查呢?
我可以将 dll 文件写入磁盘,但我需要 cs 文件。
【问题讨论】:
标签: c# .net dynamic assemblybuilder
【讨论】:
您有使用AssemblyBuilder 的要求吗?我问是因为AssemblyBuilder 不允许您在不使用反编译器的情况下查看生成的类,并且如果您生成的类非常复杂,则反编译的代码质量不会很好。
如果您使用 Reflection.Emit,您几乎处于相同的情况,因为它会生成低级 IL。
如果您确实需要查看动态生成的源代码,您最好的选择是CodeDom。这是一个例子How to: Create a Class Using CodeDOM
【讨论】:
您可以使用 Roslyn(又名“.NET 编译器平台”)一石二鸟。你需要 Microsoft.CodeAnalysis.CSharp 包。
首先,您可以使用SyntaxFactory 类生成语法节点,您可以将其组合成更大的结构(成员、方法、类、命名空间、编译单元)。
您还可以使用ToString() 或ToFullString()(带有正确的缩进和换行符等)获得语法节点的格式良好的表示,这正是您最初所寻找的。p>
网上有不少关于如何使用这个 API 的教程(如1、2),还有Roslyn Quoter 网站可以将一段C# 代码转换为SyntaxFactory 调用。
其次,您可以使用生成的CSharpSyntaxNode 创建一个CSharpSyntaxTree,您可以在CSharpCompilation 的帮助下将其编译成IL(毕竟Roslyn 是参考C# 编译器)。
如果需要,您甚至可以将生成的程序集发送到流中,从那里获取程序集的二进制数据,然后将新创建的程序集加载到当前正在执行的程序集中,并动态实例化您刚刚定义的类型。
【讨论】:
您需要使用 .NET 反射。
Ildasm.exe 无法帮助您,因为它不会创建您需要的 .cs 文件。
所以ILSpy 是来自 SharpDevelop 团队的开源 .NET 程序集浏览器和反编译器,或者是来自 Jetbrains 的 dotPeek。
根据平台,您还可以查看Mono Cecil。 Cecil 是 Jb Evain 编写的一个库,用于生成和检查 ECMA CIL 格式的程序和库。
如果您需要速度,来自 Telerik 的 JustDecompile 是一款免费的 .NET 程序集浏览和反编译工具,声称比竞争对手快 10 倍。
所有这些工具都可以让您获取现有的已编译程序集(.dll 或 .exe)并轻松浏览其中包含的符号,然后同样轻松地将程序集语言反编译回可读的 C# 和 IL。
【讨论】: