JIT編譯器將方法的IL代碼編譯成本機代碼時,會查看IL代碼中引用了哪些類型。在運行時,JIT編譯器利用程序集的TypeRef和AssemblyRef元數據表來肯定哪個程序集定義了全部引用的類型。數組
經過Assembly的Load方法加載程序集。安全
類庫須要理解類型的定義才能提供豐富的功能,就適合使用反射。性能
應用程序須要從特定程序集中加載特定類型以執行特定任務時,也要使用反射。 線程
缺點:設計
反射形成編譯時沒法保證類型安全性。對象
反射速度慢。接口
使用反射調用成員也會影響性能。用反射調用方法時,首先必須將實參打包成數組;在內部,反射必須將這些實參解包到線程棧上。進程
最好避免利用反射來訪問字段或調用方法/屬性。因使用:事件
讓類型從編譯時已知的基類型派生。內存
讓類型實現編譯時已知的接口。
3.1 發現程序集中定義的類型
3.2 類型對象的準確含義
3.3 構建Exception派生類型的層次結構
3.4 構造類型的實例
得到對Type派生對象的引用以後,就能夠構造該類型的實例了。
System.Activator的CreateInstance方法
System.Activator的CreateInstanceFrom方法
System.AppDomain的方法
System.Reflection.ConstructorInfo的Invoke實例方法
構建可擴展應用程序時,接口時是中心。可用基類型代替接口,但接口一般是首選,由於它容許加載項開發人員選擇他們本身的基類。設計:
建立「宿主SDK」(Host SDk)程序集,它定義了一個接口,接口的方法做爲宿主應用程序與加載項之間的通訊機制使用。爲接口方法參數和返回類型時,請嘗試使用MSCorLib.dll中定義的其餘接口或類型。要傳遞並返回本身的數據類型,也在「宿主SDK」程序集定義。一旦搞定接口定義,就可爲這個程序集賦予強名稱,而後把它打包並部署到合做夥伴和用戶那裏。
加載項開發人員會在加載項程序集中定義本身的類型。這些程序集將引用你的「宿主」程序集中的類型 。
建立單獨的「宿主應用程序」程序集,在其中包含你的應用程序類型。這個程序集顯然要引用「宿主SDK」程序集,並使用其中定義的類型。
MemberInfo的全部派生類型都通用的屬性和方法
成員名稱 | 成員類型 | 說明 |
Name | 一個string屬性 | 返回成員名稱 |
DeclaringType | 一個Type屬性 | 返回聲明成員的Type |
Module | 一個Module屬性 | 返回聲明成員的Module |
CustomAttributes | 該屬性返回一個IEnumerable<CustomAtrributeData> | 返回一個集合,其中每一個元素都標識了應用該成員的一個定製特性的實例。
|
如何調用成員
成員類型 | 調用成員而須要調用的方法 |
FiledInfo | 調用GetValue獲取字段的值 調用SetValue設置字段的值 |
ConstructorInfo | 調用Invoke構造類型的實例並調用構造器 |
MethodInfo | 調用Invoke來調用類型的方法 |
PropertyInfo | 調用GetValue來調用的屬性的get訪問器方法 調用SetValue來調用屬性的set訪問器方法 |
EventInfo | 調用AddEventHandler來調用事件的add訪問器方法 調用RemoveEventHanlder來調用事件的remove訪問器方法 |
許多應用程序都綁定了一組類型(Type對象)或類型呢成員(MemberInfo派生對象),並將這些對象保存在某種形式的集合中。
開發人員可使用運行時句柄代替對象以減小工做集(佔用得內存)。RuntimeTypeHandle.RuntimeFieldHandle和RuntimeMethodHandle三個類型,包含一個字段「IntPtr」,IntPtr字段是一個句柄,引用了AppDomain的Loader堆中的一個類型,字段或方法。