Reflektion und generische Typen
Vom Standpunkt der Reflektion aus betrachtet, liegt der Unterschied zwischen einem generischen Typ und einem einfachen Typ darin, dass einem generischen Typ eine Reihe von Typparametern (bei einer Definition eines generischen Typs) oder Typargumenten (bei einem konstruierten Typ) zugewiesen sind. Eine generische Methode unterscheidet sich entsprechend von einer normalen Methode.
Wenn Sie sich mit der Behandlung generischer Typen und Methoden durch Reflektion befassen, sollten Sie die beiden wesentlichen Grundsätze kennen:
Die Typparameter von Definitionen generischer Typen und Methoden werden durch Instanzen der Type-Klasse dargestellt.
Hinweis Wenn ein Type-Objekt einen generischen Typparameter darstellt, weisen viele Eigenschaften und Methoden von Type ein anderes Verhalten auf.Diese Unterschiede werden in den Themen über Eigenschaften und Methoden dokumentiert.Informationen finden Sie beispielsweise unter IsAutoClass und DeclaringType.Einige Member sind zudem nur gültig, wenn ein Type-Objekt einen generischen Typparameter darstellt.Ein Beispiel finden Sie unter GetGenericTypeDefinition.
Wenn eine Instanz von Type einen generischen Typ darstellt, enthält sie ein Array von Typen, die die Typparameter (bei Definitionen generischer Typen) oder die Typargumente (bei konstruierten Typen) darstellen. Dies gilt auch für eine Instanz der MethodInfo-Klasse, die eine generische Methode darstellt.
Reflektion stellt Methoden von Type und MethodInfo bereit, mit denen Sie auf das Array von Typparameter zugreifen und ermitteln können, ob eine Instanz von Type einen Typparameter oder einen tatsächlichen Typ darstellt.
Beispielcode, der die hier dargestellten Methoden veranschaulicht, finden Sie unter Gewusst wie: Untersuchen und Instanziieren von generischen Typen mit Reflektion.
Im Folgenden wird davon ausgegangen, dass Sie mit den Begriffen im Zusammenhang mit generischen Typen und Methoden vertraut sind, z. B. dem Unterschied zwischen Typparametern und Argumenten sowie offenen und geschlossenen konstruierten Typen. Weitere Informationen finden Sie unter Generika in .NET Framework.
Diese Übersicht enthält folgende Abschnitte:
Unterschiede zwischen generischen Typen und generischen Methoden
Generieren von geschlossenen generischen Typen
Untersuchen von Typargumenten und Typparametern
Invarianten
Verwandte Themen
Unterschiede zwischen generischen Typen und generischen Methoden
Wenn Sie einen unbekannten Typ, der von einer Instanz von Type dargestellt wird, mithilfe von Reflektion untersuchen, können Sie anhand der IsGenericType-Eigenschaft ermitteln, ob es sich dabei um einen generischen Typ handelt. Bei einem generischen Typ wird true zurückgegeben. Wenn Sie entsprechend eine unbekannte Methode untersuchen, die von einer Instanz der MethodInfo-Klasse dargestellt wird, können Sie anhand der IsGenericMethod-Eigenschaft ermitteln, ob es sich bei der unbekannten Methode um eine generische Methode handelt.
Unterschiede zwischen Definitionen generischer Typen und generischer Methoden
Sie können mithilfe der IsGenericTypeDefinition-Eigenschaft ermitteln, ob ein Type-Objekt eine Definition eines generischen Typs darstellt. Anhand der IsGenericMethodDefinition-Methode können Sie ermitteln, ob eine MethodInfo eine Definition einer generischen Methode darstellt.
Definitionen generischer Typen und Methoden sind die Vorlagen, aus denen Typen erstellt werden, die instanziiert werden können. Generische Typen in der .NET Framework-Klassenbibliothek, z. B. Dictionary<TKey, TValue>, sind Definitionen generischer Typen.
Unterschiede zwischen offenen und geschlossenen Typen bzw. Methoden
Ein generischer Typ oder eine generische Methode ist geschlossen, wenn alle zugehörigen Typparameter, inklusive sämtlicher Typparameter aller einschließenden Typen, durch instanziierbare Typen ersetzt wurden. Eine Instanz eines generischen Typs kann nur erstellt werden, wenn der Typ geschlossen ist. Wenn ein Typ offen ist, gibt die Type.ContainsGenericParameters-Eigenschaft true zurück. Für Methoden erfüllt die MethodInfo.ContainsGenericParameters-Methode die gleiche Funktion.
Zurück nach oben
Generieren von geschlossenen generischen Typen
Wenn die Definition des generische Typs oder der generischen Methode erstellt wurde, erstellen Sie anhand der MakeGenericType-Methode einen geschlossenen generischen Typ oder anhand der MakeGenericMethod-Methode eine MethodInfo für eine geschlossene generische Methode.
Abrufen der Definition des generischen Typs oder der generischen Methode
Aus einem offenen generischen Typ oder einer offenen generischen Methode, die keine Definition eines generischen Typs bzw. einer generischen Methode ist, können Sie keine Instanzen erstellen. Sie können auch keine fehlenden Typparameter angeben. Dafür benötigen Sie eine Definition eines generischen Typs oder einer generischen Methode. Rufen Sie die Definition des generischen Typs über die GetGenericTypeDefinition-Methode oder die Definition der generischen Methode über die GetGenericMethodDefinition-Methode ab.
Wenn Sie beispielsweise über ein Type-Objekt verfügen, das Dictionary<int, string> (Dictionary(Of Integer, String) in Visual Basic) darstellt und den Typ Dictionary<string, MyClass> erstellen möchten, können Sie mit der GetGenericTypeDefinition-Methode einen Type abrufen, der Dictionary<TKey, TValue> darstellt. Anschließen erzeugen Sie mit der MakeGenericType-Methode einen Type, der Dictionary<int, MyClass> darstellt.
Ein Beispiel für einen offenen generischen Typ, der kein generischer Typ ist, finden Sie später in diesem Thema unter "Typparameter oder Typargument".
Zurück nach oben
Untersuchen von Typargumenten und Typparametern
Rufen Sie mit der Type.GetGenericArguments-Methode ein Array von Type-Objekten ab, die die Typparameter oder Typargumente eines generischen Typs darstellen, und führen Sie diesen Vorgang entsprechend mit der MethodInfo.GetGenericArguments-Methode für eine generische Methode durch.
Wenn Sie wissen, dass das Type-Objekt einen Typparameter darstellt, können Sie mithilfe von Reflektion verschiedene Informationen abrufen. Sie können die Quelle des Typparameters, seine Position und seine Einschränkungen bestimmen.
Typparameter oder Typargument
Mithilfe der IsGenericParameter-Eigenschaft können Sie ermitteln, ob es sich bei einem bestimmten Element des Arrays um einen Typparameter oder ein Typargument handelt. Wenn das Element ein Typparameter ist, ist die IsGenericParameter-Eigenschaft true.
Ein generischer Typ kann offen und trotzdem keine Definition eines generischen Typs sein, wenn er sowohl über Typargumente als auch über Typparameter verfügt. Im folgenden Code ist beispielsweise die Klasse D von einem Typ abgeleitet, die erstellt wurde, indem der erste Typparameter von D durch den zweiten Typparameter von B ersetzt wurde.
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> {};
Wenn Sie ein Type-Objekt abrufen, das D<V, W> darstellt, und seinen Basistyp über die BaseType-Eigenschaft abrufen, erhalten Sie ein offenes type B<int, V>, das jedoch keine Definition eines generischen Typs ist.
Quelle eines generischen Parameters
Ein generischer Typparameter kann von dem untersuchten Typ, dem einschließenden Typ oder von einer generischen Methode stammen. Die Quelle des generischen Typparameters kann folgendermaßen bestimmt werden:
Ermitteln Sie zuerst mithilfe der DeclaringMethod-Eigenschaft, ob der Typparameter aus einer generischen Methode stammt. Wenn der Eigenschaftswert kein NULL-Verweis (Nothing in Visual Basic) ist, ist die Quelle eine generische Methode.
Handelt es sich bei der Quelle nicht um eine generische Methode, können Sie über die DeclaringType-Eigenschaft den generischen Typ ermitteln, zu dem der generische Typparameter gehört.
Wenn der Typparameter zu einer generischen Methode gehört, gibt die DeclaringType-Eigenschaft den Typ zurück, der die generische Methode deklariert hat. Dies ist für Sie ohne Bedeutung.
Position eines generischen Parameters
Es kann in Einzelfällen nötig sein, die Position eines Typparameters in der Typparameterliste seiner deklarierenden Klasse zu bestimmen. Nehmen Sie z. B. an, dass Sie über ein Type-Objekt verfügen, das den B<int, V>-Typ aus dem vorangehenden Beispiel darstellt. Über die GetGenericArguments-Methode erhalten Sie eine Liste von Typargumenten, und beim Untersuchen von V können Sie mit der DeclaringMethod-Eigenschaft und der DeclaringType-Eigenschaft erkennen, woher diese stammen. Anhand der GenericParameterPosition-Eigenschaft können Sie dann die Position in der Typparameterliste ermitteln, in der er definiert wurde. Im vorliegenden Beispiel befindet V sich an Position 0 (null ) in der Typparameterliste, in der er definiert wurde.
Basistyp und Schnittstelleneinschränkungen
Die Basistypeinschränkung und die Schnittstelleneinschränkungen eines Typparameters können mithilfe der GetGenericParameterConstraints-Methode abgerufen werden. Die Reihenfolge der Elemente des Arrays ist ohne Bedeutung. Ein Element stellt eine Schnittstelleneinschränkung dar, sofern es ein Schnittstellentyp ist.
Generische Parameterattribute
Die GenericParameterAttributes-Eigenschaft ruft einen GenericParameterAttributes-Wert ab, der die Varianz (Kovarianz oder Kontravarianz) und die besonderen Einschränkungen eines Typparameters angibt.
Kovarianz und Kontravarianz
Um zu bestimmen, ob ein Typparameter ein Kovarianz- oder Kontravarianz-Typparameter ist, wenden Sie die GenericParameterAttributes.VarianceMask-Maske auf den GenericParameterAttributes-Wert an, der von der GenericParameterAttributes-Eigenschaft zurückgegeben wird. Wenn das Ergebnis GenericParameterAttributes.None lautet, ist der Typparameter invariant. Weitere Informationen finden Sie unter Kovarianz und Kontravarianz in Generika.
Besondere Einschränkungen
Um die besonderen Einschränkungen eines Typparameters zu bestimmen, wenden Sie die GenericParameterAttributes.SpecialConstraintMask-Maske auf den GenericParameterAttributes-Wert an, der von der GenericParameterAttributes-Eigenschaft zurückgegeben wird. Wenn das Ergebnis GenericParameterAttributes.None ist, gibt es keine besonderen Einschränkungen. Ein Typparameter kann folgendermaßen eingeschränkt werden: auf einen Verweistyp, auf einen Typ, der nicht auf NULL festgelegt werden kann oder dahingehend, über einen Standardkonstruktor zu verfügen.
Zurück nach oben
Invarianten
Eine Tabelle der unveränderlichen Bedingungen für allgemeine Begriffe, die im Zusammenhang mit Reflektion für generische Typen verwendet werden, finden Sie unter Type.IsGenericType. Weitere Begriffe, die sich auf generische Methoden beziehen, finden Sie unter MethodInfo.IsGenericMethod.
Zurück nach oben
Verwandte Themen
Titel |
Beschreibung |
---|---|
Gewusst wie: Untersuchen und Instanziieren von generischen Typen mit Reflektion |
Beschreibt die Verwendung der Eigenschaften und Methoden von Type und MethodInfo zum Untersuchen generischer Typen. |
Beschreibt die Generikafunktion und wie diese in .NET Framework unterstützt wird. |
|
Gewusst wie: Definieren eines generischen Typs mit Reflektionsausgabe |
Beschreibt, wie mithilfe der Reflektionsausgabe generische Typen in dynamischen Assemblys generiert werden. |
Beschreibt die Type-Klasse und gibt Codebeispiele an, die veranschaulichen, wie Type in Verbindung mit verschiedenen Reflektionsklassen verwendet wird, um Informationen über Konstruktoren, Methoden, Felder, Eigenschaften und Ereignisse abzurufen. |
Zurück nach oben