Weerspiegeling en algemene typen
Vanuit het oogpunt van weerspiegeling is het verschil tussen een algemeen type en een gewoon type dat een algemeen type eraan is gekoppeld een set typeparameters (als het een algemene typedefinitie is) of typeargumenten (als het een samengesteld type is). Een algemene methode verschilt van een gewone methode op dezelfde manier.
Er zijn twee sleutels om te begrijpen hoe reflectie algemene typen en methoden verwerkt:
De typeparameters van algemene typedefinities en algemene methodedefinities worden vertegenwoordigd door exemplaren van de Type klasse.
Notitie
Veel eigenschappen en methoden hebben Type een ander gedrag wanneer een Type object een algemene typeparameter vertegenwoordigt. Deze verschillen worden beschreven in de artikelen over eigenschappen en methoden. Zie bijvoorbeeld IsAutoClass en DeclaringType. Daarnaast zijn sommige leden alleen geldig wanneer een Type object een algemene typeparameter vertegenwoordigt. Zie bijvoorbeeld GetGenericTypeDefinition.
Als een exemplaar van Type een algemeen type vertegenwoordigt, bevat het een matrix met typen die de typeparameters vertegenwoordigen (voor algemene typedefinities) of de typeargumenten (voor samengestelde typen). Hetzelfde geldt voor een instantie van de MethodInfo klasse die een algemene methode vertegenwoordigt.
Weerspiegeling biedt methoden van Type en MethodInfo waarmee u toegang hebt tot de matrix van typeparameters en om te bepalen of een exemplaar van Type een typeparameter of een werkelijk typetype vertegenwoordigt.
Code die de hier besproken methoden demonstreert, raadpleegt u Het volgende: Algemene typen onderzoeken en instantiëren met Weerspiegeling.
In de volgende discussie wordt ervan uitgegaan dat u bekend bent met de terminologie van generieken, zoals het verschil tussen typeparameters en argumenten en geopende of gesloten samengestelde typen. Zie Generics voor meer informatie.
Is dit een algemeen type of methode?
Wanneer u weerspiegeling gebruikt om een onbekend type te onderzoeken, vertegenwoordigd door een exemplaar van Type, gebruikt u de IsGenericType eigenschap om te bepalen of het onbekende type algemeen is. Het retourneert true
als het type algemeen is. Als u een onbekende methode onderzoekt, die wordt vertegenwoordigd door een exemplaar van de MethodInfo klasse, gebruikt u de IsGenericMethod eigenschap om te bepalen of de methode algemeen is.
Is dit een algemene type- of methodedefinitie?
Gebruik de IsGenericTypeDefinition eigenschap om te bepalen of een Type object een algemene typedefinitie vertegenwoordigt en gebruik de IsGenericMethodDefinition methode om te bepalen of een MethodInfo object een algemene methodedefinitie vertegenwoordigt.
Algemene type- en methodedefinities zijn de sjablonen waaruit instantiëerbare typen worden gemaakt. Algemene typen in de .NET-bibliotheken, zoals Dictionary<TKey,TValue>, zijn algemene typedefinities.
Is het type of de methode geopend of gesloten?
Een algemeen type of methode wordt gesloten als instantiërende typen zijn vervangen door alle typeparameters, inclusief alle typeparameters van alle typen typen. U kunt alleen een exemplaar van een algemeen type maken als het is gesloten. De Type.ContainsGenericParameters eigenschap retourneert true
als een type is geopend. Voor methoden voert de MethodBase.ContainsGenericParameters methode dezelfde functie uit.
Gesloten algemene typen genereren
Zodra u een algemene type- of methodedefinitie hebt, gebruikt u de MakeGenericType methode om een gesloten algemeen type te maken of de MakeGenericMethod methode om een MethodInfo voor een gesloten algemene methode te maken.
Het algemene type of de methodedefinitie ophalen
Als u een open algemeen type of methode hebt die geen algemene type- of methodedefinitie is, kunt u er geen exemplaren van maken en kunt u de typeparameters die ontbreken niet opgeven. U moet een algemene type- of methodedefinitie hebben. Gebruik de GetGenericTypeDefinition methode om de algemene typedefinitie of de GetGenericMethodDefinition methode te verkrijgen om de algemene methodedefinitie te verkrijgen.
Als u bijvoorbeeld een Type object hebt dat aangeeft Dictionary<int, string>
en u het type Dictionary<string, MyClass>
wilt maken, kunt u de GetGenericTypeDefinition methode gebruiken om een Type representatie Dictionary<TKey, TValue>
op te halen en vervolgens de MakeGenericType methode te gebruiken om een Type representatie Dictionary<int, MyClass>
te produceren.
Voor een voorbeeld van een open algemeen type dat geen algemeen type is, raadpleegt u de parameter Type of het argument Type.
Typeargumenten en typeparameters onderzoeken
Gebruik de Type.GetGenericArguments methode om een matrix met Type objecten te verkrijgen die de typeparameters of typeargumenten van een algemeen type vertegenwoordigen en gebruik de MethodInfo.GetGenericArguments methode om hetzelfde te doen voor een algemene methode.
Zodra u weet dat een Type object een typeparameter vertegenwoordigt, zijn er veel aanvullende vragen die kunnen worden beantwoord. U kunt de bron, de positie en de beperkingen van de typeparameter bepalen.
Parameter of typeargument typen
Als u wilt bepalen of een bepaald element van de matrix een typeparameter of een typeargument is, gebruikt u de IsGenericParameter eigenschap. De IsGenericParameter eigenschap is true
als het element een typeparameter is.
Een algemeen type kan open zijn zonder een algemene typedefinitie te zijn, in dat geval heeft het een combinatie van typeargumenten en typeparameters. In de volgende code is klasse D
bijvoorbeeld afgeleid van een type dat is gemaakt door de eerste typeparameter van D
het tweede type van B
.
class B<T, U> {}
class D<V, W> : B<int, V> {}
Class B(Of T, U)
End Class
Class D(Of V, W)
Inherits B(Of Integer, V)
End Class
generic<typename T, typename U> ref class B {};
generic<typename V, typename W> ref class D : B<int, V> {};
Als u een Type object verkrijgt dat de BaseType eigenschap vertegenwoordigt D<V, W>
en gebruikt om het basistype te verkrijgen, is het resultaat type B<int, V>
geopend, maar is het geen algemene typedefinitie.
Bron van een algemene parameter
Een algemene typeparameter kan afkomstig zijn van het type dat u onderzoekt, van een insluittype of van een algemene methode. U kunt de bron van de algemene typeparameter als volgt bepalen:
- Gebruik eerst de DeclaringMethod eigenschap om te bepalen of de typeparameter afkomstig is van een algemene methode. Als de eigenschapswaarde geen null-verwijzing is, is de bron een algemene methode.
- Als de bron geen algemene methode is, gebruikt u de DeclaringType eigenschap om het algemene type te bepalen waartoe de parameter van het algemene type behoort.
Als de typeparameter deel uitmaakt van een algemene methode, retourneert de DeclaringType eigenschap het type dat de algemene methode heeft gedeclareerd, wat niet relevant is.
Positie van een algemene parameter
In zeldzame gevallen is het nodig om de positie van een typeparameter te bepalen in de typeparameterlijst van de declaratieklasse. Stel dat u een Type object hebt dat het B<int, V>
type uit het voorgaande voorbeeld vertegenwoordigt. De GetGenericArguments methode geeft u een lijst met typeargumenten en wanneer u onderzoekt V
, kunt u de DeclaringMethod en DeclaringType eigenschappen gebruiken om te ontdekken waar deze vandaan komt. Vervolgens kunt u de eigenschap gebruiken om de GenericParameterPosition positie ervan te bepalen in de parameterlijst van het type waar deze is gedefinieerd. In dit voorbeeld V
bevindt zich op positie 0 (nul) in de typeparameterlijst waar deze is gedefinieerd.
Beperkingen voor basistype en interface
Gebruik de GetGenericParameterConstraints methode om de beperking van het basistype en de interfacebeperkingen van een typeparameter te verkrijgen. De volgorde van de elementen van de matrix is niet significant. Een element vertegenwoordigt een interfacebeperking als dit een interfacetype is.
Algemene parameterkenmerken
De GenericParameterAttributes eigenschap krijgt een GenericParameterAttributes waarde die de variantie (covariantie of contravariantie) en de speciale beperkingen van een typeparameter aangeeft.
Covariantie en contravariantie
Als u wilt bepalen of een typeparameter covariant of contravariant is, past u het GenericParameterAttributes.VarianceMask masker toe op de GenericParameterAttributes waarde die door de GenericParameterAttributes eigenschap wordt geretourneerd. Als het resultaat is GenericParameterAttributes.None, is de typeparameter invariant. Zie Covariantie en Contravariantie voor meer informatie.
Speciale beperkingen
Als u de speciale beperkingen van een typeparameter wilt bepalen, past u het GenericParameterAttributes.SpecialConstraintMask masker toe op de GenericParameterAttributes waarde die door de GenericParameterAttributes eigenschap wordt geretourneerd. Als het resultaat is GenericParameterAttributes.None, zijn er geen speciale beperkingen. Een typeparameter kan worden beperkt tot een verwijzingstype, om een niet-null-waardetype te zijn en om een parameterloze constructor te hebben.
Invarianten
Zie voor een tabel met de invariante voorwaarden voor algemene termen in weerspiegeling voor algemene typen Type.IsGenericType. Zie voor aanvullende termen met betrekking tot algemene methoden MethodBase.IsGenericMethod.