Type.MakeGenericType(Type[]) Methode

Definition

Ersetzt die Elemente eines Arrays von Typen für die Typparameter der aktuellen generischen Typdefinition und gibt ein Type Objekt zurück, das den resultierenden konstruierten Typ darstellt.

public:
 abstract Type ^ MakeGenericType(... cli::array <Type ^> ^ typeArguments);
public:
 virtual Type ^ MakeGenericType(... cli::array <Type ^> ^ typeArguments);
public abstract Type MakeGenericType(params Type[] typeArguments);
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("The native code for this instantiation might not be available at runtime.")]
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")]
public virtual Type MakeGenericType(params Type[] typeArguments);
public virtual Type MakeGenericType(params Type[] typeArguments);
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")]
public virtual Type MakeGenericType(params Type[] typeArguments);
abstract member MakeGenericType : Type[] -> Type
[<System.Diagnostics.CodeAnalysis.RequiresDynamicCode("The native code for this instantiation might not be available at runtime.")>]
[<System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")>]
abstract member MakeGenericType : Type[] -> Type
override this.MakeGenericType : Type[] -> Type
abstract member MakeGenericType : Type[] -> Type
override this.MakeGenericType : Type[] -> Type
[<System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")>]
abstract member MakeGenericType : Type[] -> Type
override this.MakeGenericType : Type[] -> Type
Public MustOverride Function MakeGenericType (ParamArray typeArguments As Type()) As Type
Public Overridable Function MakeGenericType (ParamArray typeArguments As Type()) As Type

Parameter

typeArguments
Type[]

Ein Array von Typen, die durch die Typparameter des aktuellen generischen Typs ersetzt werden sollen.

Gibt zurück

A Type representing the constructed type formed by substituting the elements of typeArguments for the type parameters of the current generic type.

Attribute

Ausnahmen

Der aktuelle Typ stellt keine generische Typdefinition dar. Das heißt, IsGenericTypeDefinition gibt zurück false.

typeArguments ist null.

-oder-

Jedes Element von typeArguments ist null.

Die Anzahl der Elemente in typeArguments ist nicht mit der Anzahl der Typparameter in der aktuellen generischen Typdefinition identisch.

-oder-

Jedes Element von typeArguments erfüllt nicht die für den entsprechenden Typparameter des aktuellen generischen Typs angegebenen Einschränkungen.

-oder-

typeArguments enthält ein Element, bei dem es sich um einen Zeigertyp (IsPointertrueReturns ) handelt, einen By-Ref-Typ (IsByRef returns true) oder Void.

Die aufgerufene Methode wird in der Basisklasse nicht unterstützt. Abgeleitete Klassen müssen eine Implementierung bereitstellen.

Beispiele

Im folgenden Beispiel wird die MakeGenericType Methode verwendet, um einen konstruierten Typ aus der generischen Typdefinition für den Dictionary<TKey,TValue> Typ zu erstellen. Der konstruierte Typ stellt ein Dictionary<TKey,TValue> Objekt Test mit Zeichenfolgenschlüsseln dar.

using System;
using System.Reflection;
using System.Collections.Generic;

public class Test
{
    public static void Main()
    {
        Console.WriteLine("\r\n--- Create a constructed type from the generic Dictionary type.");

        // Create a type object representing the generic Dictionary 
        // type, by omitting the type arguments (but keeping the 
        // comma that separates them, so the compiler can infer the
        // number of type parameters).      
        Type generic = typeof(Dictionary<,>);
        DisplayTypeInfo(generic);

        // Create an array of types to substitute for the type
        // parameters of Dictionary. The key is of type string, and
        // the type to be contained in the Dictionary is Test.
        Type[] typeArgs = { typeof(string), typeof(Test) };

        // Create a Type object representing the constructed generic
        // type.
        Type constructed = generic.MakeGenericType(typeArgs);
        DisplayTypeInfo(constructed);

        // Compare the type objects obtained above to type objects
        // obtained using typeof() and GetGenericTypeDefinition().
        Console.WriteLine("\r\n--- Compare types obtained by different methods:");

        Type t = typeof(Dictionary<String, Test>);
        Console.WriteLine("\tAre the constructed types equal? {0}", t == constructed);
        Console.WriteLine("\tAre the generic types equal? {0}", 
            t.GetGenericTypeDefinition() == generic);
    }

    private static void DisplayTypeInfo(Type t)
    {
        Console.WriteLine("\r\n{0}", t);

        Console.WriteLine("\tIs this a generic type definition? {0}", 
            t.IsGenericTypeDefinition);

        Console.WriteLine("\tIs it a generic type? {0}", 
            t.IsGenericType);

        Type[] typeArguments = t.GetGenericArguments();
        Console.WriteLine("\tList type arguments ({0}):", typeArguments.Length);
        foreach (Type tParam in typeArguments)
        {
            Console.WriteLine("\t\t{0}", tParam);
        }
    }
}

/* This example produces the following output:

--- Create a constructed type from the generic Dictionary type.

System.Collections.Generic.Dictionary`2[TKey,TValue]
        Is this a generic type definition? True
        Is it a generic type? True
        List type arguments (2):
                TKey
                TValue

System.Collections.Generic.Dictionary`2[System.String, Test]
        Is this a generic type definition? False
        Is it a generic type? True
        List type arguments (2):
                System.String
                Test

--- Compare types obtained by different methods:
        Are the constructed types equal? True
        Are the generic types equal? True
 */
open System
open System.Collections.Generic

type Test() = class end

let displayTypeInfo (t: Type) =
    printfn $"\r\n{t}"

    printfn $"\tIs this a generic type definition? {t.IsGenericTypeDefinition}" 

    printfn $"\tIs it a generic type? {t.IsGenericType}"

    let typeArguments = t.GetGenericArguments()
    printfn $"\tList type arguments ({typeArguments.Length}):"
    for tParam in typeArguments do
        printfn $"\t\t{tParam}"

printfn "\r\n--- Create a constructed type from the generic Dictionary type."

// Create a type object representing the generic Dictionary 
// type, by calling .GetGenericTypeDefinition().
let generic = typeof<Dictionary<_,_>>.GetGenericTypeDefinition()
displayTypeInfo generic

// Create an array of types to substitute for the type
// parameters of Dictionary. The key is of type string, and
// the type to be contained in the Dictionary is Test.
let typeArgs = [| typeof<string>; typeof<Test> |]

// Create a Type object representing the constructed generic type.
let constructed = generic.MakeGenericType typeArgs
displayTypeInfo constructed

(* This example produces the following output:

--- Create a constructed type from the generic Dictionary type.

System.Collections.Generic.Dictionary`2[TKey,TValue]
        Is this a generic type definition? True
        Is it a generic type? True
        List type arguments (2):
                TKey
                TValue

System.Collections.Generic.Dictionary`2[System.String, Test]
        Is this a generic type definition? False
        Is it a generic type? True
        List type arguments (2):
                System.String
                Test
 *)

Public Class Test
    Public Shared Sub Main2()
        Console.WriteLine(vbCrLf & "--- Create a constructed type from the generic Dictionary type.")

        ' Create a type object representing the generic Dictionary 
        ' type, by omitting the type arguments (but keeping the 
        ' comma that separates them, so the compiler can infer the
        ' number of type parameters).
        Dim generic As Type = GetType(Dictionary(Of ,))
        DisplayTypeInfo(generic)

        ' Create an array of types to substitute for the type
        ' parameters of Dictionary. The key is of type string, and
        ' the type to be contained in the Dictionary is Test.
        Dim typeArgs() As Type = {GetType(String), GetType(Test)}

        ' Create a Type object representing the constructed generic
        ' type.
        Dim constructed As Type = generic.MakeGenericType(typeArgs)
        DisplayTypeInfo(constructed)

        ' Compare the type objects obtained above to type objects
        ' obtained using GetType() and GetGenericTypeDefinition().
        Console.WriteLine(vbCrLf & "--- Compare types obtained by different methods:")

        Dim t As Type = GetType(Dictionary(Of String, Test))
        Console.WriteLine(vbTab & "Are the constructed types equal? " _
            & (t Is constructed))
        Console.WriteLine(vbTab & "Are the generic types equal? " _
            & (t.GetGenericTypeDefinition() Is generic))
    End Sub

    Private Shared Sub DisplayTypeInfo(ByVal t As Type)
        Console.WriteLine(vbCrLf & t.ToString())

        Console.WriteLine(vbTab & "Is this a generic type definition? " _ 
            & t.IsGenericTypeDefinition)

        Console.WriteLine(vbTab & "Is it a generic type? " _ 
            & t.IsGenericType)

        Dim typeArguments() As Type = t.GetGenericArguments()
        Console.WriteLine(vbTab & "List type arguments ({0}):", _
            typeArguments.Length)
        For Each tParam As Type In typeArguments       
            Console.WriteLine(vbTab & vbTab & tParam.ToString())
        Next
    End Sub
End Class

' This example produces the following output:
'
'--- Create a constructed type from the generic Dictionary type.
'
'System.Collections.Generic.Dictionary'2[TKey,TValue]
'        Is this a generic type definition? True
'        Is it a generic type? True
'        List type arguments (2):
'                TKey
'                TValue
'
'System.Collections.Generic.Dictionary`2[System.String,Test]
'        Is this a generic type definition? False
'        Is it a generic type? True
'        List type arguments (2):
'                System.String
'                Test
'
'--- Compare types obtained by different methods:
'        Are the constructed types equal? True
'        Are the generic types equal? True

Hinweise

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 Basedarstellt, 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.

Note

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.

Note

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

Gilt für:

Weitere Informationen