第二十三章 程序集加載和反射

23.1 程序集加載

JIT編譯器將方法的IL代碼編譯成本機代碼時,會查看IL代碼中引用了哪些類型。在運行時,JIT編譯器利用程序集的TypeRef和AssemblyRef元數據表來肯定哪個程序集定義了全部引用的類型。數組

經過Assembly的Load方法加載程序集。安全

23.2 使用反射構建動態可擴展應用程序

 類庫須要理解類型的定義才能提供豐富的功能,就適合使用反射。性能

應用程序須要從特定程序集中加載特定類型以執行特定任務時,也要使用反射。 線程

23.3 反射的性能

 缺點:設計

反射形成編譯時沒法保證類型安全性。對象

反射速度慢。接口

使用反射調用成員也會影響性能。用反射調用方法時,首先必須將實參打包成數組;在內部,反射必須將這些實參解包到線程棧上。進程

最好避免利用反射來訪問字段或調用方法/屬性。因使用:事件

讓類型從編譯時已知的基類型派生。內存

讓類型實現編譯時已知的接口。

3.1 發現程序集中定義的類型

3.2 類型對象的準確含義

3.3 構建Exception派生類型的層次結構

3.4 構造類型的實例

  得到對Type派生對象的引用以後,就能夠構造該類型的實例了。

System.Activator的CreateInstance方法

System.Activator的CreateInstanceFrom方法

System.AppDomain的方法

System.Reflection.ConstructorInfo的Invoke實例方法

23.4 設計支持加載項的應用程序

構建可擴展應用程序時,接口時是中心。可用基類型代替接口,但接口一般是首選,由於它容許加載項開發人員選擇他們本身的基類。設計:

  建立「宿主SDK」(Host SDk)程序集,它定義了一個接口,接口的方法做爲宿主應用程序與加載項之間的通訊機制使用。爲接口方法參數和返回類型時,請嘗試使用MSCorLib.dll中定義的其餘接口或類型。要傳遞並返回本身的數據類型,也在「宿主SDK」程序集定義。一旦搞定接口定義,就可爲這個程序集賦予強名稱,而後把它打包並部署到合做夥伴和用戶那裏。

  加載項開發人員會在加載項程序集中定義本身的類型。這些程序集將引用你的「宿主」程序集中的類型 。

  建立單獨的「宿主應用程序」程序集,在其中包含你的應用程序類型。這個程序集顯然要引用「宿主SDK」程序集,並使用其中定義的類型。

23.5 使用反射發現類型的成員

 5.1 發現類型的成員

MemberInfo的全部派生類型都通用的屬性和方法

成員名稱 成員類型 說明
Name 一個string屬性 返回成員名稱
DeclaringType 一個Type屬性 返回聲明成員的Type
Module 一個Module屬性 返回聲明成員的Module
CustomAttributes 該屬性返回一個IEnumerable<CustomAtrributeData>

返回一個集合,其中每一個元素都標識了應用該成員的一個定製特性的實例。

 

5.2  調用類型的成員

如何調用成員

 成員類型 調用成員而須要調用的方法 
 FiledInfo

調用GetValue獲取字段的值

調用SetValue設置字段的值 

 ConstructorInfo 調用Invoke構造類型的實例並調用構造器 
 MethodInfo 調用Invoke來調用類型的方法 
 PropertyInfo

調用GetValue來調用的屬性的get訪問器方法

調用SetValue來調用屬性的set訪問器方法 

EventInfo

調用AddEventHandler來調用事件的add訪問器方法

調用RemoveEventHanlder來調用事件的remove訪問器方法

 

5.3 使用綁定句柄減小進程的內存消耗

許多應用程序都綁定了一組類型(Type對象)或類型呢成員(MemberInfo派生對象),並將這些對象保存在某種形式的集合中。

開發人員可使用運行時句柄代替對象以減小工做集(佔用得內存)。RuntimeTypeHandle.RuntimeFieldHandle和RuntimeMethodHandle三個類型,包含一個字段「IntPtr」,IntPtr字段是一個句柄,引用了AppDomain的Loader堆中的一個類型,字段或方法。

相關文章
相關標籤/搜索