System.Type.MakeGenericType-Methode
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 offenem Format erstellt werden, d. h. einige ihrer Typargumente können Typparameter sein, um generische Methoden oder Typen einzuschließen. Sie können solche geöffneten konstruierten Typen verwenden, wenn Sie dynamische Assemblys ausgeben. Betrachten Sie beispielsweise die Klassen Base
und Derived
den 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 in einer dynamischen Assembly zu generieren Derived
, 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 Type zurückgegebene MakeGenericType Objekt entspricht dem Type Abrufen der GetType Methode des resultierenden konstruierten Typs oder der Methode eines konstruierten Typs, der GetType anhand derselben generischen Typdefinition mit denselben Typargumenten erstellt wurde.
Hinweis
Ein Array generischer Typen ist nicht selbst ein generischer Typ. Sie können keinen Arraytyp wie C<T>[]
(Dim ac() As C(Of T)
in Visual Basic) aufrufenMakeGenericType. Rufen Sie zum Erstellen eines geschlossenen generischen Typs C<T>[]
die generische Typdefinition C<T>
auf, rufen Sie GetElementTypeMakeGenericType die generische Typdefinition auf, um den konstruierten Typ zu erstellen, und rufen Sie schließlich die MakeArrayType Methode für den 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, für Begriffe, die für die Reflektion mit generischen Methoden verwendet werden, finden Sie in den Hinweisen zur Eigenschaft IsGenericType.
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
weist zwei Typparameter auf U
und T
ist der erste Parameter des Typparameters der eingeschlossenen Klasse. Ebenso weist die Typparameterliste der geschachtelten Klasse Innermost1
drei Typparameter auf, T
U
und zwar mit T
und V
U
aus den eingeschlossenen Klassen. Die geschachtelte Klasse Innermost2
verfügt über zwei Typparameter, T
die U
aus den eingeschlossenen Klassen stammen.
Wenn die Parameterliste des eingeschlossenen Typs mehr als einen Typparameter aufweist, sind alle Typparameter in der Typparameterliste des geschachtelten Typs enthalten.
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. Rufen Sie die MakeGenericType Methode mit einem Array mit drei Typen auf, um eine Instanz von Innermost1
T, U und V zu erstellen. Rufen Sie die MakeGenericType Methode mit einem Array mit zwei Typen auf, um eine Instanz von Innermost2
T und U zu erstellen.
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 befinden sich die Typparameter nicht innerhalb der Textkörper der geschachtelten 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.