2015-03-13 20 views
0

我知道反射是通過「讀取元數據」來完成的,但是當它被編譯時,它是如何存儲的?此外,元數據佔用了多少空間?如果一個反編譯器可以從元數據重新生成我的整個c#程序,它是否存儲與編寫的代碼幾乎相同的元數據?Reflection如何在機器語言級別上工作

+0

請參閱[Common Intermediate Language](http://en.wikipedia.org/wiki/Common_Intermediate_Language)。反思發生在機器語言級別之上。 – JLRishe 2015-03-13 14:27:11

+1

Relection不會停留在機器語言層,而是停留在IL層。您可以通過查看PDB文件的大小來確定元數據的大小。反射不需要PDB,因爲它只能查看EXE;但是,不會出現符號。反編譯器可以使用IL層重新生成C#程序;但是,您可以將它湮沒,以便沒有人能真正理解正在發生的事情。元數據不是那麼大,因爲它只存在於兩種形式的PDB文件中,並且在大會的標題信息中,您可以使用工具ILDASM輕鬆查看它。 – 2015-03-13 14:28:43

+0

@JohnPeters作爲回答而不是評論會更好。 – 2015-03-13 14:45:18

回答

0

如果您使用ildasm打開裝配,則可以看到元數據。您將看到類的列表,應用於這些類的屬性,引用的DLL,方法和簽名,......您必須閱讀.NET可執行文件的.dll格式的規範才能準確瞭解它需要多少空間並且所有這些都以比組件更緊湊的格式存儲在組件中。

然後可以點擊一個方法,你會看到代碼,編譯成中間語言。您會注意到它與您的源代碼完全不同。反編譯器,如免費的ilspy無法重新生成C#程序,正如您寫的一樣。生成的IL並不像x86組合那樣低級,但它足夠高,反編譯器可以做得非常好。足以讓你可以理解代碼在做什麼。

有關堆棧溢出的其他一些問題涉及此主題。 What are the `exact` differences between .NET dll and a normal dll?

也嘗試一些關於「便攜式可執行」AKA PE格式的搜索。 http://www.codeproject.com/Articles/12585/The-NET-File-Format

我不太確定它有多大的實際存儲大小。您將不得不深入查看格式。或者嘗試編譯一些代碼並將代碼大小與可執行文件大小進行比較。

0

我知道反射是通過「讀取元數據」來完成的,但是當編譯時它是如何存儲的? ?此外,元數據佔用了多少空間 ?如果一個反編譯器可以從元數據重新生成我的整個c#程序 ,它是否存儲與編寫的 代碼幾乎相同的元數據?

當您的編譯器編譯代碼時,它將被存儲爲IL代碼。您的代碼被逐字保存的思路是不正確的。 「反編譯器」或反射器並不完美。他們幾乎重新創建了最初編譯的內容。如果你仔細看看你寫的代碼和反映的代碼,它們不完全一樣。

0

.NET語言族存在於名爲Common Language Runtime(CLR)的運行時環境中。當您編譯.NET語言(如C#)時,您正在將C#語言轉換爲由「中間語言」(IL)及其相關元數據組成的程序集。直到運行時才發生JIT編譯,並將IL轉換爲彙編語言代碼。

反編譯器可以通過讀取IL並使用規則生成C#或VB.NET或任何支持的.NET語言來生成代碼。您沒有獲得原始代碼,而是基於IL包含的新生成代碼和反編譯器完成的映射。

就空間而言,您可以使用Windows資源管理器查看程序集和PDB文件以查看磁盤上的文件大小。

看看如何實施反射是一個徒勞的IMO演習。實施細節並不重要。瞭解到您可以將代碼視爲數據很重要。完成這項任務的級別很多。爲了更深入瞭解,我建議您使用MSDN或查看其他語言,如clojure