我知道反射是通過「讀取元數據」來完成的,但是當它被編譯時,它是如何存儲的?此外,元數據佔用了多少空間?如果一個反編譯器可以從元數據重新生成我的整個c#程序,它是否存儲與編寫的代碼幾乎相同的元數據?Reflection如何在機器語言級別上工作
回答
如果您使用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
我不太確定它有多大的實際存儲大小。您將不得不深入查看格式。或者嘗試編譯一些代碼並將代碼大小與可執行文件大小進行比較。
我知道反射是通過「讀取元數據」來完成的,但是當編譯時它是如何存儲的? ?此外,元數據佔用了多少空間 ?如果一個反編譯器可以從元數據重新生成我的整個c#程序 ,它是否存儲與編寫的 代碼幾乎相同的元數據?
當您的編譯器編譯代碼時,它將被存儲爲IL代碼。您的代碼被逐字保存的思路是不正確的。 「反編譯器」或反射器並不完美。他們幾乎重新創建了最初編譯的內容。如果你仔細看看你寫的代碼和反映的代碼,它們不完全一樣。
.NET語言族存在於名爲Common Language Runtime(CLR)的運行時環境中。當您編譯.NET語言(如C#)時,您正在將C#語言轉換爲由「中間語言」(IL)及其相關元數據組成的程序集。直到運行時才發生JIT編譯,並將IL轉換爲彙編語言代碼。
反編譯器可以通過讀取IL並使用規則生成C#或VB.NET或任何支持的.NET語言來生成代碼。您沒有獲得原始代碼,而是基於IL包含的新生成代碼和反編譯器完成的映射。
就空間而言,您可以使用Windows資源管理器查看程序集和PDB文件以查看磁盤上的文件大小。
看看如何實施反射是一個徒勞的IMO演習。實施細節並不重要。瞭解到您可以將代碼視爲數據很重要。完成這項任務的級別很多。爲了更深入瞭解,我建議您使用MSDN或查看其他語言,如clojure。
- 1. 面向機器的高級語言和高級語言之間的區別
- 2. 準備好的語句如何在SQL級別上工作?
- 3. MSSQL上的BusinessObject:如何在會話級別更改語言?
- 4. 定時器和延遲如何在低級別上工作
- 5. Intellij IDEA Ruby語言級別
- 6. 語言級別的線程
- 7. R語言如何工作
- 8. 如何更改Android Studio上的項目語言級別
- 9. 語言interop如何在.Net中工作?
- 10. JNI如何在內存級別工作
- 11. ptrace是否在用戶級別或內核級別上工作?
- 12. 如何在Android Studio中爲新項目選擇語言級別?
- 13. 如何在Java中定位較低的語言級別
- 14. 如何用機器語言調用printf
- 15. 機器語言如何運行?
- 16. 如何添加選擇首選語言(CodeIgniter的語言級別)的鏈接?
- 17. 多語言支持如何在Drupal 8等平臺上工作?
- 18. 如何在android上設置語音識別語言?
- 19. 在C語言中工作
- 20. 在低級語言
- 21. 自定義授權在操作級別上工作,但不在控制器級別上
- 22. Solaris機器上的語言設置
- 23. Android支持庫如何在目標SDK級別上工作?
- 24. 可執行文件如何在位/字節級別上工作?
- 25. 數組通常如何在低級別上工作?
- 26. gwt事件如何在低級別上工作
- 27. 網絡工作者如何在單核心機器上工作
- 28. 「API級別分析器」工具可能如何工作?
- 29. 如何在mac機器上升級Jenkins
- 30. Xtend force java 7語言級別
請參閱[Common Intermediate Language](http://en.wikipedia.org/wiki/Common_Intermediate_Language)。反思發生在機器語言級別之上。 – JLRishe 2015-03-13 14:27:11
Relection不會停留在機器語言層,而是停留在IL層。您可以通過查看PDB文件的大小來確定元數據的大小。反射不需要PDB,因爲它只能查看EXE;但是,不會出現符號。反編譯器可以使用IL層重新生成C#程序;但是,您可以將它湮沒,以便沒有人能真正理解正在發生的事情。元數據不是那麼大,因爲它只存在於兩種形式的PDB文件中,並且在大會的標題信息中,您可以使用工具ILDASM輕鬆查看它。 – 2015-03-13 14:28:43
@JohnPeters作爲回答而不是評論會更好。 – 2015-03-13 14:45:18