Type.MakeGenericType(Type[]) Methode

Definition

Ersetzt die Typparameter der aktuellen generischen Typdefinition durch die Elemente eines Arrays von Typen und gibt ein Type-Objekt zurück, das den resultierenden konstruierten Typ darstellt.Substitutes the elements of an array of types for the type parameters of the current generic type definition and returns a Type object representing the resulting constructed type.

public:
 virtual Type ^ MakeGenericType(... cli::array <Type ^> ^ typeArguments);
public virtual Type MakeGenericType (params Type[] typeArguments);
abstract member MakeGenericType : Type[] -> Type
override this.MakeGenericType : Type[] -> Type
Public Overridable Function MakeGenericType (ParamArray typeArguments As Type()) As Type

Parameter

typeArguments
Type[]

Ein Array von Typen, die die Typparameter des aktuellen generischen Typs ersetzen sollen.An array of types to be substituted for the type parameters of the current generic type.

Gibt zurück

Ein Type, der den konstruierten Typ darstellt, der durch Ersetzen der Typparameter des aktuellen generischen Typs durch die Elemente von typeArguments erstellt wurde.A Type representing the constructed type formed by substituting the elements of typeArguments for the type parameters of the current generic type.

Ausnahmen

Der aktuelle Typ stellt keine generische Typdefinition dar.The current type does not represent a generic type definition. Das heißt, IsGenericTypeDefinition gibt false zurück.That is, IsGenericTypeDefinition returns false.

typeArguments ist null.typeArguments is null.

- oder --or- Ein beliebiges Element von typeArguments ist null.Any element of typeArguments is null.

Die Anzahl der Elemente im typeArguments entspricht nicht der Anzahl von Typparametern in der aktuellen generischen Typdefinition.The number of elements in typeArguments is not the same as the number of type parameters in the current generic type definition.

- oder --or- Ein beliebiges Element von typeArguments erfüllt nicht die Einschränkungen, die für den entsprechenden Typparameter des aktuellen generischen Typs angegeben wurden.Any element of typeArguments does not satisfy the constraints specified for the corresponding type parameter of the current generic type.

- oder --or- typeArguments enthält ein Element, das ein Zeigertyp (IsPointer gibt true zurück), vom Typ „by-ref“ (IsByRef gibt true zurück) oder Void ist.typeArguments contains an element that is a pointer type (IsPointer returns true), a by-ref type (IsByRef returns true), or Void.

Die aufgerufene Methode wird in der Basisklasse nicht unterstützt.The invoked method is not supported in the base class. Abgeleitete Klassen müssen eine Implementation angeben.Derived classes must provide an implementation.

Beispiele

Im folgenden Beispiel wird die MakeGenericType -Methode verwendet, um einen konstruierten Typ aus der generischen Dictionary<TKey,TValue> Typdefinition für den-Typ zu erstellen.The following example uses the MakeGenericType method to create a constructed type from the generic type definition for the Dictionary<TKey,TValue> type. Der konstruierte Typ stellt eine Dictionary<TKey,TValue> von Test Objekten mit Zeichen folgen Schlüsseln dar.The constructed type represents a Dictionary<TKey,TValue> of Test objects with string keys.

using namespace System;
using namespace System::Reflection;
using namespace System::Collections::Generic;

namespace Example
{
    public ref class Test
    {
    public:
        static void CreateConstructedType(void)
        {      
            Console::WriteLine("\r\n--- Create a constructed type"
                " from the generic Dictionary`2 type.");
            
            // Create a type object representing 
            // the generic Dictionary`2 type.
            Type^ genericType = Type::GetType(
                "System.Collections.Generic.Dictionary`2");
            if (genericType != nullptr)
            {  
                DisplayTypeInfo(genericType);
            }
            else
            {
                Console::WriteLine("The type is not found");
                return;
            }
            
            // Create an array of types to substitute for the type
            // parameters of Dictionary`2. 
            // The key is of type string, and the type to be 
            // contained in the Dictionary`2 is Test.
            array<Type^>^ typeArgs = {String::typeid, Test::typeid};
            Type^ constructedType = 
                genericType->MakeGenericType(typeArgs);
            DisplayTypeInfo(constructedType);
            
            // 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^ definedType = Dictionary<String^, Test^>::typeid;
            Console::WriteLine("\tAre the constructed types "
                "equal? {0}", definedType == constructedType);
            Console::WriteLine("\tAre the generic types equal? {0}", 
                definedType->GetGenericTypeDefinition() == genericType);
        }

    private:
        static void DisplayTypeInfo(Type^ typeToDisplay)
        {   
            Console::WriteLine("\r\n{0}", typeToDisplay);
            Console::WriteLine("\tIs this a generic type definition? "
                "{0}", typeToDisplay->IsGenericTypeDefinition);
            Console::WriteLine("\tIs it a generic type? "
                "{0}", typeToDisplay->IsGenericType);
            
            array<Type^>^ typeArguments = 
                typeToDisplay->GetGenericArguments();
            Console::WriteLine("\tList type arguments ({0}):", 
                typeArguments->Length);
            
            for each (Type^ typeArgument in typeArguments)
            {   
                Console::WriteLine("\t\t{0}", typeArgument);
            }
        }
    };
}

int main(void)
{
    Example::Test::CreateConstructedType();
}

/* This example produces the following output:

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

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

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
 */
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
 */
Imports System.Reflection
Imports System.Collections.Generic

Public Class Test
    Public Shared Sub Main()
        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 MakeGenericType der-Methode können Sie Code schreiben, der den Typparametern einer generischen Typdefinition bestimmte Typen zuweist, wodurch Type ein-Objekt erstellt wird, das einen bestimmten konstruierten Typ darstellt.The MakeGenericType method allows you to write code that assigns specific types to the type parameters of a generic type definition, thus creating a Type object that represents a particular constructed type. Sie können dieses Type Objekt verwenden, um Lauf Zeit Instanzen des konstruierten Typs zu erstellen.You can use this Type object to create run-time instances of the constructed type.

Mit MakeGenericType erstellte Typen können geöffnet werden, d. h., einige ihrer Typargumente können Typparameter von einschließenden generischen Methoden oder Typen sein.Types constructed with MakeGenericType can be open, that is, some of their type arguments can be type parameters of enclosing generic methods or types. Bei der Ausgabe dynamischer Assemblys können solche geöffneten konstruierten Typen verwendet werden.You might use such open constructed types when you emit dynamic assemblies. Stellen Sie sich z. b Base . Derived die Klassen und im folgenden Code vor.For example, consider the classes Base and Derived in the following code.

generic<typename T, typename U>
    public ref class Base { };
generic<typename V>
    public ref class Derived : Base<int, V> { };
public class Base<T, U> { }
public class Derived<V> : 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 Derived einer dynamischen Assembly zu generieren, muss der Basistyp erstellt werden.To generate Derived in a dynamic assembly, it is necessary to construct its base type. Um dies zu erreichen, müssen MakeGenericType Sie die- Type Methode für ein- BaseObjekt aufrufen, das die- Int32 Klasse mit den generischen DerivedTypargumenten und dem Typparameter V von darstelltTo do this, call the MakeGenericType method on a Type object representing the class Base, using the generic type arguments Int32 and the type parameter V from Derived. Da Typen und generische Typparameter beide durch Type -Objekte dargestellt werden, kann ein Array, das beide enthält, an die MakeGenericType -Methode übermittelt werden.Because types and generic type parameters are both represented by Type objects, an array containing both can be passed to the MakeGenericType method.

Hinweis

Ein konstruierter Typ, Base<int, V> wie z. b., ist beim Ausgeben von Code MakeGenericType nützlich, aber Sie können die-Methode für diesen Typ nicht abrufen, da es sich nicht um eine generische TypdefinitionA constructed type such as Base<int, V> is useful when emitting code, but you cannot call the MakeGenericType method on this type because it is not a generic type definition. Um einen geschlossenen konstruierten Typ zu erstellen, der instanziiert werden kann, GetGenericTypeDefinition rufen Sie zuerst die Type -Methode auf, um ein- MakeGenericType Objekt abzurufen, das die generische Typdefinition darstelltTo create a closed constructed type that can be instantiated, first call the GetGenericTypeDefinition method to get a Type object representing the generic type definition and then call MakeGenericType with the desired type arguments.

Das Type Type von MakeGenericType zurückgegebene Objekt ist das gleiche wie das, das durch GetType den Aufruf der-Methode des resultierenden konstruierten GetType Typs abgerufen wird, oder die-Methode eines konstruierten Typs, der aus demselben generischen erstellt wurde. Typdefinition mit denselben Typargumenten.The Type object returned by MakeGenericType is the same as the Type obtained by calling the GetType method of the resulting constructed type, or the GetType method of any constructed type that was created from the same generic type definition using the same type arguments.

Hinweis

Ein Array generischer Typen ist nicht selbst ein generischer Typ.An array of generic types is not itself a generic type. Es ist nicht MakeGenericType möglich, für einen ArraytypDim ac() As C(Of T) C<T>[] wie (in Visual Basic) aufzurufen.You cannot call MakeGenericType on an array type such as C<T>[] (Dim ac() As C(Of T) in Visual Basic). Um einen geschlossenen generischen Typ aus C<T>[]zu erstellen GetElementType , rufen Sie auf, um C<T>die generische MakeGenericType Typdefinition abzurufen. Rufen Sie die generische Typdefinition auf, um den konstruierten Typ zu erstellen, und rufen Sie schließlich die MakeArrayType -Methode auf der konstruierte Typ zum Erstellen des Arraytyps.To construct a closed generic type from C<T>[], call GetElementType to obtain the generic type definition C<T>; call MakeGenericType on the generic type definition to create the constructed type; and finally call the MakeArrayType method on the constructed type to create the array type. Das gleiche gilt für Zeiger Typen und- ref Typen (ByRef in Visual Basic).The same is true of pointer types and ref types (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.For a list of the invariant conditions for terms used in generic reflection, see the IsGenericType property remarks.

Geschachtelte TypenNested Types

Wenn ein generischer Typ mithilfe C#von, C++oder Visual Basic definiert wird, sind die zugehörigen nerischen Typen alle generisch.If a generic type is defined using C#, C++, or Visual Basic, then its nested types are all generic. Dies ist auch dann der Fall, wenn die in der Liste für die Typen übergebenen Typen keine eigenen Typparameter aufweisen, da alle drei Sprachen die Typparameter der einschließenden Typen in den Typparameter Listen der in einem Typ untergeordneten Typen enthalten.This is true even if the nested types have no type parameters of their own, because all three languages include the type parameters of enclosing types in the type parameter lists of nested types. Beachten Sie die folgenden Klassen:Consider the following classes:

generic<typename T> public ref class Outermost
{
public:
    generic<typename U> ref class Inner
    {
    public:
        generic<typename V> ref class Innermost1 {};
        ref class Innermost2 {};
    };
};
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 Typparameter Liste der-Klasse Inner hat zwei Typparameter, T und U, der erste ist der Typparameter der einschließenden Klasse.The type parameter list of the nested class Inner has two type parameters, T and U, the first of which is the type parameter of its enclosing class. Entsprechend Innermost1 verfügt die Typparameter Liste der-Klasse über die drei TTypparameter,, Uund V, mit T und U aus den zugehörigen einschließenden Klassen.Similarly, the type parameter list of the nested class Innermost1 has three type parameters, T, U, and V, with T and U coming from its enclosing classes. Die-Klasse Innermost2 verfügt über zwei Typparameter, T und U, die von ihren einschließenden Klassen stammen.The nested class Innermost2 has two type parameters, T and U, which come from its enclosing classes.

Wenn die Parameterliste des einschließenden Typs mehr als einen Typparameter aufweist, werden alle Typparameter in der Reihenfolge in der Typparameter Liste des untergeordneten Typs eingefügt.If the parameter list of the enclosing type has more than one type parameter, all the type parameters in order are included in the type parameter list of the nested type.

Um einen generischen Typ aus der generischen Typdefinition für einen Typ zu erstellen, wird MakeGenericType die-Methode mit dem Array aufgerufen, das durch Verkettung der Typargument Arrays aller einschließenden Typen, beginnend mit dem äußersten generischen Typ, beginnend mit dem äußersten generischen Typ und endende mit dem Typargument Array des in den arsted Typ selbst, wenn es über eigene Typparameter verfügt.To construct a generic type from the generic type definition for a nested type, call the MakeGenericType method with the array formed by concatenating the type argument arrays of all the enclosing types, beginning with the outermost generic type, and ending with the type argument array of the nested type itself, if it has type parameters of its own. Um eine Instanz von Innermost1zu erstellen, rufen Sie die-Methode mit einem Array auf, das drei Typen enthält, die MakeGenericType T, U und V zugewiesen werden sollen. Um eine Instanz von Innermost2zu erstellen, rufen Sie die-Methode mit einem Array auf, das zwei Typen enthält, die MakeGenericType T und U zugewiesen werden sollen.To create an instance of Innermost1, call the MakeGenericType method with an array containing three types, to be assigned to T, U, and V. To create an instance of Innermost2, call the MakeGenericType method with an array containing two types, to be assigned to T and U.

Die Sprachen propagieren die Typparameter von einschließenden Typen auf diese Weise, sodass Sie die Typparameter eines einschließenden Typs verwenden können, um Felder von geschachtelte Types zu definieren.The languages propagate the type parameters of enclosing types in this fashion so you can use the type parameters of an enclosing type to define fields of nested types. Andernfalls befinden sich die Typparameter nicht im Gültigkeitsbereich innerhalb der Texte der geschachtelten Typen.Otherwise, the type parameters would not be in scope within the bodies of the nested types. Es ist möglich, die Typparameter von einschließenden Typen zu definieren, indem Sie Code in dynamischen Assemblys oder mithilfe von Ilasm. exe (Il-Assembler)ausgeben.It is possible to define nested types without propagating the type parameters of enclosing types, by emitting code in dynamic assemblies or by using the Ilasm.exe (IL Assembler). Beachten Sie den folgenden Code für den MSIL-Assembler:Consider the following code for the MSIL 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 diese Typparameter nicht im Gültigkeitsbereich liegen.In this example, it is not possible to define a field of type T or U in class Innermost, because those type parameters are not in scope. Der folgende Assemblycode definiert die Klassen, die sich so Verhalten, wie Sie C++in, Visual Basic und C#definiert werden:The following assembler code defines nested classes that behave the way they would if defined in C++, Visual Basic, and C#:

.class public Outer<T> {  
    .class nested public Inner<T, U> {  
        .class nested public Innermost<T, U, V> {  
        }  
    }  
}  

Sie können den Ildasm. exe (IL-Disassembler) verwenden, um in den Sprachen auf hoher Ebene definierte in der Sprache definierte Klassen zu untersuchen und dieses Benennungs Schema zu beobachten.You can use the Ildasm.exe (IL Disassembler) to examine nested classes defined in the high-level languages and observe this naming scheme.

Gilt für:

Siehe auch