動態類型產生的可回收組件
「可回收組件」是動態組件,不需要卸載其建立所在的應用程式定義域即可予以卸載。 可以回收可回收組件所使用的所有受控和非受控記憶體與其包含的類型。 組件名稱這類資訊會從內部資料表中予以移除。
若要啟用卸載,請在建立動態組件時使用 AssemblyBuilderAccess.RunAndCollect 旗標。 組件是暫時性 (也就是無法儲存它) 並受限於可回收組件的限制一節中所述的限制。 通用語言執行平台 (CLR) 會在您發行所有與組件建立關聯的物件時自動卸載可回收組件。 在所有其他方面,可回收組件的建立和使用方式都會與其他動態組件相同。
可回收組件的存留期
可回收組件的存留期受控於是否有其所含類型以及從這些型別所建立之物件的參考。 只要有下列其中一或多個項目,通用語言執行平台就不會卸載組件 (T
是組件中定義的任何類型):
T
的執行個體。T
陣列的執行個體。將
T
作為它的其中一個型別引數的泛型型別執行個體。 這包含T
的泛型集合,即使該集合是空的也是一樣。表示
T
的 Type 或 TypeBuilder 執行個體。重要
您必須發行所有代表組件各部分的物件。 定義
T
的 ModuleBuilder 會保留 TypeBuilder 的參考,而 AssemblyBuilder 物件會保留 ModuleBuilder 的參考,因此必須發行這些物件的參考。 即使建構T
時已使用 LocalBuilder 或 ILGenerator 還是會防止卸載。依另一個動態定義型別
T1
之T
的靜態參考,而此動態定義型別仍然可以透過執行程式碼來取得。 例如,T1
可能衍生自T
,或T
可能是T1
的方法中的參數類型。屬於
T
之靜態欄位的ByRef
。RuntimeTypeHandle、RuntimeFieldHandle 或 RuntimeMethodHandle,可以參考
T
或T
的元件。任何反映物件執行個體,可以間接或直接用來存取代表
T
的 Type 物件。 例如,T
的 Type 物件可以從其項目類型為T
的陣列類型取得,或從具有T
作為型別引數的泛型型別取得。任何執行緒呼叫堆疊上的方法
M
,其中M
是T
的方法或是組件中所定義的模型層級方法。定義於組件模組中之靜態方法的委派。
如果組件中的一個類型或一個方法在此清單中只有一個項目,則執行階段無法卸載組件。
注意
除非已針對清單中的所有項目執行完成項,否則執行階段不會實際卸載組件。
基於追蹤存留期的目的,會將產生可回收組件時所建立和使用的建構化泛型型別 (例如,C# 中的 List<int>
或 Visual Basic 中的 List(Of Integer)
) 視為已定義在包含泛型型別定義的組件中,或包含它的其中一個型別引號定義的組件中。 使用的確切組件是實作詳細資料,而且可能會變更。
可回收組件的限制
下列限制適用於可回收組件:
靜態參考
一般動態組件中的類型不能有可回收組件中所定義型別的靜態參考。 例如,如果您定義繼承自可回收組件中類型的一般類型,則會擲回 NotSupportedException 例外狀況。 可回收組件中的類型可以有另一個可回收組件中類型的靜態參考,但這會將已參考組件的存留期擴充為參考中組件的存留期。
下列限制適用於 .NET Framework 中的可回收組件:
COM Interop
在可回收組件內無法定義 COM 介面,而且可回收組件內的型別執行個體無法轉換為 COM 物件。 可回收組件中的類型不能作為 COM 可呼叫包裝函式 (CCW) 或執行階段可呼叫包裝函式 (RCW)。 不過,可回收組件中的類型可以使用可實作 COM 介面的物件。
平台叫用
具有 DllImportAttribute 屬性的方法在可回收組件中進行宣告時就不會進行編譯。 程式OpCodes.Calli 指令不能用於可回收組件中的類型實作,而且無法將此等類型封送處理至非受控程式碼。 不過,您可以使用非可回收組件中所宣告的進入點來呼叫原生程式碼。
封送處理
無法封送處理可回收組件中所定義的物件 (特別是委派)。 這是所有暫時發出型別的限制。
組件載入
反映發出是唯一支援載入可回收組件的機制。 無法卸載使用其他任何形式的組件載入所載入的組件。
內容繫結物件
不支援內容靜態變數。 可回收組件中的類型無法擴充 ContextBoundObject。 不過,可回收組件中的程式碼可以使用在其他位置定義的內容繫結物件。
執行緒靜態資料
不支援執行緒靜態變數。
下列限制適用於 .NET Framework 和 .NET 9 之前 .NET 版本中的可回收組件:
具有
FixedAddressValueTypeAttribute
的靜態欄位可回收組件中定義的靜態欄位無法套用 FixedAddressValueTypeAttribute 屬性。