Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieser Artikel enthält ergänzende Hinweise zur Referenzdokumentation für diese API.
Mit der MakeGenericType Methode können Sie Code schreiben, der bestimmten Typen den Typparametern einer generischen Typdefinition zuweist, wodurch ein Type Objekt erstellt wird, das einen bestimmten konstruierten Typ darstellt. Mit diesem Type Objekt können Sie Laufzeitinstanzen des erstellten Typs erstellen.
Typen, die mit MakeGenericType erstellt werden, können offen sein, das heißt, einige ihrer Typargumente können Typparameter von umgebenden generischen Methoden oder Typen sein. Sie können solche offen konstruierten Typen verwenden, wenn Sie dynamische Assemblies emittieren. Betrachten Sie beispielsweise die Klassen Base
und Derived
im folgenden Code.
public class Base<T, U> { }
public class Derived<V> : Base<int, V> { }
type Base<'T, 'U>() = class end
type Derived<'V>() = inherit Base<int, 'V>()
Public Class Base(Of T, U)
End Class
Public Class Derived(Of V)
Inherits Base(Of Integer, V)
End Class
Um Derived
in einer dynamischen Assembly zu erzeugen, ist es erforderlich, den Basistyp zu konstruieren. Rufen Sie dazu die MakeGenericType Methode für ein Type Objekt auf, das die Klasse Base
darstellt, mithilfe der generischen Typargumente Int32 und des Typparameters V
aus Derived
. Da Typen und generische Typparameter beide durch Type Objekte dargestellt werden, kann ein Array, das beide enthält, an die MakeGenericType Methode übergeben werden.
Hinweis
Ein konstruierter Typ wie Base<int, V>
z. B. ist nützlich, wenn Code emittiert wird, aber Sie können die MakeGenericType Methode für diesen Typ nicht aufrufen, da es sich nicht um eine generische Typdefinition handelt. Um einen geschlossenen konstruierten Typ zu erstellen, der instanziiert werden kann, rufen Sie zuerst die GetGenericTypeDefinition Methode auf, um ein Type Objekt abzurufen, das die generische Typdefinition darstellt, und rufen Sie dann mit den gewünschten Typargumenten auf MakeGenericType .
Das durch Type zurückgegebene MakeGenericType-Objekt ist dasselbe wie das Type, das durch Aufruf der GetType-Methode des resultierenden konstruierten Typs oder der GetType-Methode eines konstruierten Typs, der aus derselben generischen Typdefinition mit denselben Typargumenten erstellt wurde, erhalten wird.
Hinweis
Ein Array generischer Typen ist nicht selbst ein generischer Typ. Sie können MakeGenericType nicht auf einen Arraytyp wie C<T>[]
(Dim ac() As C(Of T)
in Visual Basic) anwenden. Um einen geschlossenen generischen Typ zu erstellen, rufen Sie C<T>[]
auf, um die generische Typdefinition GetElementType zu erhalten; rufen Sie C<T>
auf der generischen Typdefinition auf, um den konstruierten Typ zu erstellen; und rufen Sie schließlich die MakeGenericType-Methode auf dem konstruierten Typ auf, um den Arraytyp zu erstellen. Dasselbe gilt für Zeigertypen und ref
-typen (ByRef
in Visual Basic).
Eine Liste der invarianten Bedingungen für Begriffe, die in generischer Spiegelung verwendet werden, finden Sie in den IsGenericType Eigenschaftenshinweisen.
Geschachtelte Typen
Wenn ein generischer Typ mit C#, C++ oder Visual Basic definiert ist, sind die geschachtelten Typen generisch. Dies gilt auch dann, wenn die geschachtelten Typen keine eigenen Typparameter aufweisen, da alle drei Sprachen die Typparameter der Eingeschlossenen Typen in die Typparameterlisten geschachtelter Typen enthalten. Berücksichtigen Sie die folgenden Klassen:
public class Outermost<T>
{
public class Inner<U>
{
public class Innermost1<V> {}
public class Innermost2 {}
}
}
Public Class Outermost(Of T)
Public Class Inner(Of U)
Public Class Innermost1(Of V)
End Class
Public Class Innermost2
End Class
End Class
End Class
Die Typparameterliste der geschachtelten Klasse Inner
umfasst zwei Typparameter, T
und U
, wobei der erste Typparameter zur umgebenden Klasse gehört. Ebenso weist die Typparameterliste der geschachtelten Klasse Innermost1
drei Typparameter auf: T
, U
und V
, wobei T
und U
aus den umschließenden Klassen stammen. Die geschachtelte Klasse Innermost2
verfügt über zwei Typparameter, T
und U
, die aus den umgebenden Klassen stammen.
Wenn die Parameterliste des umschließenden Typs mehr als einen Typparameter hat, werden alle Typparameter in der Reihenfolge in die Typparameterliste des verschachtelten Typs aufgenommen.
Um einen generischen Typ aus der generischen Typdefinition für einen geschachtelten Typ zu erstellen, rufen Sie die MakeGenericType Methode mit dem Array auf, das durch Verketten der Typargumentarrays aller eingeschlossenen Typen gebildet wird, beginnend mit dem äußersten generischen Typ und endet mit dem Typargumentarray des geschachtelten Typs selbst, wenn er Typparameter besitzt. Um eine Instanz von Innermost1
zu erstellen, rufen Sie die MakeGenericType Methode mit einem Array auf, das drei Typen enthält, die T, U und V zugewiesen werden sollen. Um eine Instanz von Innermost2
zu erstellen, rufen Sie die MakeGenericType Methode mit einem Array auf, das zwei Typen enthält, die T und U zugewiesen werden sollen.
In den Sprachen werden die Typparameter der eingeschlossenen Typen auf diese Weise weitergegeben, sodass Sie die Typparameter eines eingeschlossenen Typs verwenden können, um Felder geschachtelter Typen zu definieren. Andernfalls wären die Typparameter nicht im Geltungsbereich innerhalb der Körper der verschachtelten Typen. Es ist möglich, geschachtelte Typen zu definieren, ohne die Typparameter der eingeschlossenen Typen zu verteilen, indem Code in dynamischen Assemblys oder mithilfe der Ilasm.exe (IL Assembler) emittiert wird. Beachten Sie den folgenden Code für den CIL-Assembler:
.class public Outer<T> {
.class nested public Inner<U> {
.class nested public Innermost {
}
}
}
In diesem Beispiel ist es nicht möglich, ein Feld vom Typ T
oder U
in der Klasse Innermost
zu definieren, da sich diese Typparameter nicht im Bereich befinden. Der folgende Assemblercode definiert geschachtelte Klassen, die sich wie in C++, Visual Basic und C# verhalten würden:
.class public Outer<T> {
.class nested public Inner<T, U> {
.class nested public Innermost<T, U, V> {
}
}
}
Mit dem Ildasm.exe (IL Disassembler) können Sie geschachtelte Klassen untersuchen, die in den allgemeinen Sprachen definiert sind, und dieses Benennungsschema beobachten.