使用反映發出定義型別
更新:2007 年 11 月
型別是使用 ModuleBuilder.DefineType 方法定義於動態模組的範圍中。DefineType 會傳回 TypeBuilder。在這個主題中,型別名稱一定是包括命名空間的完整路徑名稱。例如,如果型別名稱為 Aaa.Bbb.Ccc,Aaa.Bbb 即被認定是命名空間。
反映發出提供下列選項來定義型別:
以指定名稱來定義類別或介面。
以指定名稱和屬性 (Attribute) 來定義類別或介面。
以指定名稱、屬性和基底類別來定義類別。
以指定名稱、屬性、基底類別和類別實作的介面集合來定義類別。
以指定名稱、屬性、基底類別和封裝大小來定義類別。
以指定名稱、屬性、基底類別和類別大小為整體來定義類別。
以指定名稱、屬性、基底類別、封裝大小和類別大小為整體來定義類別。
使用型別之前,必須先呼叫 TypeBuilder.CreateType 方法。CreateType 完成型別的建立。呼叫 CreateType 之後,呼叫端就可以具現化型別 (使用 Activator.CreateInstance 方法) 並叫用型別的成員 (使用 Type.InvokeMember 方法)。已經呼叫 CreateType 之後再叫用會變更型別實作的方法,是錯誤的做法。例如,如果呼叫端嘗試加入新成員至型別的話,Common Language Runtime 會擲回例外狀況 (Exception)。
類別初始設定式是使用 TypeBuilder.DefineTypeInitializer 方法建立。DefineTypeInitializer 會傳回 ConstructorBuilder。
巢狀型別是使用其中一個 TypeBuilder.DefineNestedType 方法定義。
TypeBuilder.AddDeclarativeSecurity 方法會將宣告式安全性加入至建置的型別。您可以呼叫 AddDeclarativeSecurity 數次,而每次呼叫都會指定安全性動作 (例如 Demand、Assert、Deny) 和適用該動作的使用權限集合。
屬性
介面使用 TypeAttributes.Interface 和 TypeAttributes.Abstract 屬性來指定。
使用 TypeAttributes.Sealed 屬性來指定具體類別 (不能擴充的類別)。
有數個屬性可以決定型別可視性。請參閱 TypeAttributes 列舉型別的描述。
如果 TypeAttributes.LayoutSequential 已指定,類別載入器會配置欄位,以便從中繼資料中讀取它們。類別載入器會考慮指定的封裝大小,但忽略任何指定的欄位位移 (Offset)。中繼資料保留發出欄位定義的順序。即使橫向合併,中繼資料都不會重新排列欄位定義。載入器將認可指定的欄位位移,只要 TypeAttributes.ExplicitLayout 被指定。
已知的問題
反映發出不會驗證實作介面的非抽象類別,是否已經實作介面中宣告的所有方法。然而,如果類別不實作介面中宣告的所有方法,執行階段即不會載入類別。
雖然 TypeBuilder 衍生自 Type,一些定義於 Type 類別中的抽象方法並不會在 TypeBuilder 中完整實作。這些 TypeBuilder 方法會擲回 NotSupportedException。藉由使用 Type.GetType 或是 Assembly.GetType 擷取建立的型別,並反映至擷取的型別,即可獲得想要的功能。