Zestawy kolekcjonowane dla dynamicznego generowania typów
Zestawy zbieralne to zestawy dynamiczne, które można zwolnić bez zwalniania domeny aplikacji, w której zostały utworzone. Wszystkie zarządzane i niezarządzane pamięci używane przez zestaw zbieralny i typy, które zawiera, można odzyskać. Informacje takie jak nazwa zestawu są usuwane z tabel wewnętrznych.
Aby włączyć zwalnianie, użyj flagi AssemblyBuilderAccess.RunAndCollect podczas tworzenia zestawu dynamicznego. Zestaw jest przejściowy (czyli nie można go zapisać) i podlega ograniczeniom opisanym w sekcji Ograniczenia dotyczące zestawów zbieralnych. Środowisko uruchomieniowe języka wspólnego (CLR) zwalnia zestaw zbieralny automatycznie po zwolnieniu wszystkich obiektów skojarzonych z zestawem. W każdym innym zakresie zestawy zbieralne są tworzone i używane w taki sam sposób jak inne zestawy dynamiczne.
Okres istnienia zestawów zbieralnych
Okres istnienia zestawu zbieralnego jest kontrolowany przez istnienie odwołań do typów, które zawiera, oraz obiektów utworzonych na podstawie tych typów. Środowisko uruchomieniowe języka wspólnego nie zwalnia zestawu, o ile istnieje co najmniej jeden z następujących typów (T
jest dowolnym typem zdefiniowanym w zestawie):
Wystąpienie elementu
T
.Wystąpienie tablicy .
T
Wystąpienie typu ogólnego, które ma
T
jako jeden z argumentów typu. Obejmuje to kolekcjeT
ogólne , nawet jeśli ta kolekcja jest pusta.Wystąpienie elementu Type lub TypeBuilder , które reprezentuje
T
.Ważne
Należy zwolnić wszystkie obiekty reprezentujące części zestawu. Element ModuleBuilder definiujący
T
przechowuje odwołanie do TypeBuilderobiektu , a AssemblyBuilder obiekt przechowuje odwołanie do ModuleBuilderobiektu , dlatego należy zwolnić odwołania do tych obiektów. Nawet istnienie obiektu LocalBuilder lub ILGenerator używanego w konstrukcjiT
zapobiega rozładowaniu.Statyczne odwołanie do
T
innego dynamicznie zdefiniowanego typuT1
, który jest nadal osiągalny przez wykonanie kodu. Na przykładT1
może pochodzić zT
klasy lubT
może być typem parametruT1
w metodzie .A
ByRef
do pola statycznego, które należy doT
.Element RuntimeTypeHandle, RuntimeFieldHandlelubRuntimeMethodHandle, który odwołuje się do
T
składnika lub .T
Wystąpienie dowolnego obiektu odbicia, którego można użyć pośrednio lub bezpośrednio w celu uzyskania dostępu do obiektu reprezentującego Type
T
obiekt . Na przykład Type obiekt dlaT
elementu można uzyskać z typu tablicy, którego typ elementu toT
, lub z typu ogólnego, który maT
jako argument typu.Metoda
M
na stosie wywołań dowolnego wątku, gdzieM
jest metodą lub metodąT
na poziomie modułu, która jest zdefiniowana w zestawie.Delegat do metody statycznej zdefiniowanej w module zestawu.
Jeśli tylko jeden element z tej listy istnieje tylko dla jednego typu lub jednej metody w zestawie, środowisko uruchomieniowe nie może zwolnić zestawu.
Uwaga
Środowisko uruchomieniowe nie zwalnia zestawu, dopóki finalizatory nie zostaną uruchomione dla wszystkich elementów na liście.
Do celów śledzenia okresu istnienia skonstruowany typ ogólny, taki jak List<int>
(w języku C#) lub List(Of Integer)
(w Visual Basic), który został utworzony i używany w generowaniu zestawu zbieralnego, jest uznawany za zdefiniowany w zestawie zawierającym definicję typu ogólnego lub w zestawie zawierającym definicję jednego z argumentów typu. Dokładny używany zestaw jest szczegółem implementacji i może ulec zmianie.
Ograniczenia dotyczące zestawów zbieralnych
Następujące ograniczenia dotyczą zestawów zbieralnych:
Odwołania statyczne
Typy w zwykłym zestawie dynamicznym nie mogą zawierać statycznych odwołań do typów zdefiniowanych w zestawie zbieralnym. Jeśli na przykład zdefiniujesz zwykły typ, który dziedziczy z typu w zestawie zbieralnym NotSupportedException , zgłaszany jest wyjątek. Typ w zestawie zbieralnym może mieć statyczne odwołania do typu w innym zestawie zbieralnym, ale wydłuża to okres istnienia zestawu, do których odwołuje się zestaw, do okresu istnienia zestawu odwołującego się.
Następujące ograniczenia dotyczą zestawów zbieralnych w programie .NET Framework:
Międzyoperajności MODELU COM
Interfejsy COM nie można zdefiniować w zestawie zbieralnym i nie można przekonwertować żadnych wystąpień typów w zestawie zbieralnym na obiekty COM. Typ w zestawie zbieralnym nie może służyć jako otoka wywoływana COM (CCW) lub wywoływana otoka środowiska uruchomieniowego (RCW). Jednak typy w zestawach zbieralnych mogą używać obiektów implementujących interfejsy COM.
Wywołanie platformy
Metody, które mają DllImportAttribute atrybut, nie będą kompilowane po zadeklarowaniu ich w zestawie zbieralnym. Instrukcji OpCodes.Calli nie można używać w implementacji typu w zestawie zbieralnym, a takie typy nie mogą być rozdzielane do niezarządzanego kodu. Można jednak wywołać kod natywny przy użyciu punktu wejścia zadeklarowanego w zestawie, który nie jest zbieralny.
Marshaling
Obiekty (w szczególności delegaty), które są zdefiniowane w zestawach zbieralnych, nie mogą być marshalled. Jest to ograniczenie dotyczące wszystkich typów emitowanych przejściowych.
Ładowanie zestawu
Emocje emitowanie jonów jest jedynym mechanizmem obsługiwanym do ładowania zestawów zbieralnych. Nie można zwolnić zestawów ładowanych przy użyciu jakiejkolwiek innej formy ładowania zestawu.
Obiekty powiązane kontekstowo
Zmienne statyczne kontekstowe nie są obsługiwane. Typy w zestawie zbieralnym nie mogą rozszerzać ContextBoundObjectelementu . Jednak kod w zestawach zbieralnych może używać obiektów powiązanych kontekstowo, które są zdefiniowane gdzie indziej.
Dane statyczne wątku
Zmienne statyczne wątku nie są obsługiwane.
Następujące ograniczenia dotyczą zestawów zbieralnych w programach .NET Framework i .NET wcześniejszych niż .NET 9:
Pola statyczne z
FixedAddressValueTypeAttribute
Pola statyczne zdefiniowane w zestawach zbieralnych nie mogą mieć zastosowanego atrybutu FixedAddressValueTypeAttribute .