Übersicht über Reflektion und generische Typen und Methoden

Aktualisiert: November 2007

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 Übersicht über Generika in .NET Framework.

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.

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".

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 Eigenschaftenwert 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.

Besondere Einschränkungen

Die GenericParameterAttributes-Eigenschaft ruft einen GenericParameterAttributes-Wert ab, der die besonderen Einschränkungen angibt. 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.

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.

Siehe auch

Aufgaben

Gewusst wie: Untersuchen und Instanziieren von generischen Typen mit Reflektion

Konzepte

Übersicht über Generika in .NET Framework

Anzeigen von Typinformationen

Referenz

Type

MethodInfo

Type.IsGenericType

MethodInfo.IsGenericMethod