Reflection如何在机器语言级别上工作

时间:2015-03-13 14:23:06

标签: c# .net

我知道反射是通过“读取元数据”完成的,但是在编译时,它是如何存储的?此外,元数据占用了多少空间?如果反编译器可以从元数据中重新生成我的整个c#程序,它是否存储了几乎与编写的代码一样多的元数据?

3 个答案:

答案 0 :(得分:0)

  

我知道反射是通过“阅读元数据”完成的,但确实如此   编译后,如何存储?此外,占用了多少空间   从元数据?如果反编译器可以重新生成我的整个c#程序   从元数据来看,它存储的元数据几乎和写入的一样多   码?

当编译器编译代码时,它会被存储为IL代码。您的代码实际保存的心态是不正确的。 “反编译器”或反射器并不完美。他们几乎重新创建了最初编译的内容。如果仔细查看您编写的代码和反映的代码,它们就不完全相同。

答案 1 :(得分:0)

如果使用 ildasm 打开装配,则可以看到元数据。您将看到类的列表,应用于类的属性,引用的DLL,方法和签名,......您必须阅读.NET可执行文件的.dll格式的规范,以确切了解它需要多少空间所有这些都以比组件更紧凑的格式存储在组件中。

然后可以单击某个方法,您将看到编译为中间语言的代码。您会注意到它与您的源代码完全不同。诸如免费的 ilspy 之类的反编译器无法像您编写的那样重新生成C#程序 。生成的IL并不像x86程序集那样低级,但它足够高,反编译器可以做得非常好。足够你可以理解代码在做什么。

关于此主题的堆栈溢出还有一些其他问题。 What are the `exact` differences between .NET dll and a normal dll?

还尝试对“Portable Executable”AKA PE格式进行一些搜索。 http://www.codeproject.com/Articles/12585/The-NET-File-Format

我不太确定实际的存储空间大小。你必须深入研究格式才能看到。或者尝试编译一些代码并将代码大小与可执行文件大小进行比较。

答案 2 :(得分:0)

.NET系列语言位于名为Common Language Runtime(CLR)的运行时环境中。当您编译.NET语言(如C#)时,您正在将C#语言转换为由"中间语言"组成的程序集。 (IL)及其相关的元数据。直到运行时才发生JIT编译并将IL转换为汇编语言代码。

反编译器可以通过读取IL并使用规则生成C#或VB.NET或任何支持的.NET语言来生成代码。您没有获得原始代码,而是基于IL包含的任何内容以及反编译器完成的映射而生成的新代码。

就空间而言,您可以使用Windows资源管理器查看程序集和PDB文件以在磁盘上查看其文件大小。

看看如何实施反思是徒劳的IMO。实施细节并不重要。了解您可以将代码视为数据非常重要。完成此任务有各种级别。为了更深入了解,我建议MSDN或查看其他语言,例如clojure