Type.MakeGenericType(Type[]) Type.MakeGenericType(Type[]) Type.MakeGenericType(Type[]) Type.MakeGenericType(Type[]) Method

Определение

Замещает элементы массива типов для параметров определения текущего универсального типа и возвращает объект Type, представляющий сконструированный результирующий тип.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

Параметры

typeArguments
Type[]

Массив типов, который должен быть замещен параметрами типа текущего универсального типа.An array of types to be substituted for the type parameters of the current generic type.

Возвраты

Type представляет сконструированный тип, сформированный путем замещения элементов объекта typeArguments параметрами текущего универсального типа.A Type representing the constructed type formed by substituting the elements of typeArguments for the type parameters of the current generic type.

Исключения

Текущий тип не представляет определение универсального типа.The current type does not represent a generic type definition. То есть IsGenericTypeDefinition возвращает false.That is, IsGenericTypeDefinition returns false.

typeArguments null.is null.

-или--or- Любой элемент typeArguments имеет значение null.Any element of typeArguments is null.

Количество элементов в typeArguments не совпадает с количеством параметров типа в текущем определении универсального типа.The number of elements in typeArguments is not the same as the number of type parameters in the current generic type definition.

-или--or- Элементы typeArguments не соответствуют ограничениям, указанным для соответствующего параметра типа текущего определения универсального типа.Any element of typeArguments does not satisfy the constraints specified for the corresponding type parameter of the current generic type.

-или--or- typeArguments содержит элемент, который является типом указателя (IsPointer возвращает true), типом доступа по ссылке (IsByRef возвращает true) или Void.contains an element that is a pointer type (IsPointer returns true), a by-ref type (IsByRef returns true), or Void.

Вызванный метод не поддерживается в базовом классе.The invoked method is not supported in the base class. Реализацию должны обеспечивать производные классы.Derived classes must provide an implementation.

Примеры

В следующем примере используется MakeGenericType метод для создания сконструированного типа из определения универсального типа для Dictionary<TKey,TValue> типа.The following example uses the MakeGenericType method to create a constructed type from the generic type definition for the Dictionary<TKey,TValue> type. Представляет сконструированный тип Dictionary<TKey,TValue> из Test объектов со строковыми ключами.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
Imports System.Reflection
Imports System.Collections.Generic
Imports Microsoft.VisualBasic

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

Комментарии

MakeGenericType Метод позволяет написать код, который назначает определенные типы параметров типа определения универсального типа, тем самым создавая Type , представляющий определенный сконструированный тип.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. Это можно использовать Type объект для создания экземпляров во время выполнения сконструированного типа.You can use this Type object to create run-time instances of the constructed type.

Конструировать типы с MakeGenericType могут быть открыты, то есть некоторые их аргументы могут быть параметры типа заключающих универсальные методы и типы.Types constructed with MakeGenericType can be open, that is, some of their type arguments can be type parameters of enclosing generic methods or types. Такие открытые сконструированные типы можно использовать при выпуске динамических сборок.You might use such open constructed types when you emit dynamic assemblies. Например, рассмотрим классы Base и Derived в следующем коде.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

Для создания Derived в динамической сборке, бывает необходимо построить его базовый тип.To generate Derived in a dynamic assembly, it is necessary to construct its base type. Чтобы сделать это, вызовите MakeGenericType метод Type объект, представляющий класс Base, используя аргументы универсального типа Int32 и параметр типа V из Derived.To 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. Так как типы и параметры универсального типа, оба представлены Type объектов, можно передать массив, содержащий оба MakeGenericType метод.Because types and generic type parameters are both represented by Type objects, an array containing both can be passed to the MakeGenericType method.

Примечание

Сконструированный тип, такой как Base<int, V> будет полезно при запуске выпуска кода, но нельзя вызывать MakeGenericType метод для этого типа, так как он не является определением универсального типа.A 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. Для создания закрытого сконструированного типа, которое может быть создано, сначала вызовите GetGenericTypeDefinition метод для получения Type объект, представляющий определение универсального типа, а затем вызвать MakeGenericType с аргументами требуемому типу.To 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.

Type Объект, возвращаемый MakeGenericType совпадает со значением Type получен путем вызова GetType метод итоговый сконструированный тип, или GetType метод любого сконструированный тип, который был создан с использованием того же универсального Определение типа, с теми же аргументами типа.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.

Примечание

Массив универсальных типов сама по себе не универсального типа.An array of generic types is not itself a generic type. Нельзя вызывать MakeGenericType массива введите например C<T>[] (Dim ac() As C(Of T) в Visual Basic).You cannot call MakeGenericType on an array type such as C<T>[] (Dim ac() As C(Of T) in Visual Basic). Для создания закрытого универсального типа из C<T>[], вызовите GetElementType для получения определения универсального типа C<T>; вызвать MakeGenericType в определении универсального типа для создания сконструированного типа; и Наконец вызовите MakeArrayType метод сконструированный тип, чтобы создать тип массива.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. То же самое относится и к типы указателей и ref типов (ByRef в Visual Basic).The same is true of pointer types and ref types (ByRef in Visual Basic).

Список неизменяемых условий для терминов, используемых в отражении универсальных типов, см. в примечаниях к описанию свойства IsGenericType.For a list of the invariant conditions for terms used in generic reflection, see the IsGenericType property remarks.

Вложенные типыNested Types

Если универсальный тип определен с помощью C#, C++ или Visual Basic, его вложенные типы являются универсальными.If a generic type is defined using C#, C++, or Visual Basic, then its nested types are all generic. Это справедливо, даже если вложенные типы не имеют тип параметров собственные, так как все три языка включают параметры типа заключающих типов в список параметров вложенных типов.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. Рассмотрим следующие классы: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

Список параметров типа вложенного класса Inner имеет два параметра типа, T и U, первая из которых является параметром типа включающего класса.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. Аналогичным образом, список параметров типа вложенного класса Innermost1 принимает три параметра типа, T, U, и V, с помощью T и U ожидается классами.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. Вложенный класс Innermost2 имеет два параметра типа, T и U, который поставляется с классами.The nested class Innermost2 has two type parameters, T and U, which come from its enclosing classes.

Если список параметров данного включающего типа имеет более одного параметра типа, все параметры типа в порядке будут включены в списке параметров типа вложенного типа.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.

Для конструирования универсального типа из определения универсального типа для вложенного типа, вызовите MakeGenericType метод с массивом, сформированном путем объединения всех заключающих типов, начиная с внешней универсального типа, и заканчивая массивов аргументов Массив аргументов типа вложенного типа, если он имеет свои собственные параметры типа.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. Чтобы создать экземпляр Innermost1, вызовите MakeGenericType метод с массив, содержащий три типа, присваиваемое T, U и V. Чтобы создать экземпляр Innermost2, вызовите MakeGenericType метод с массив, содержащий два типа, присваиваемое T и U.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.

Языки программирования распространяют параметры типа заключающих типов таким образом, чтобы использовать параметры типа вмещающего типа для определения полей вложенных типов.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. В противном случае параметры типа в области в телах вложенные типы не будет.Otherwise, the type parameters would not be in scope within the bodies of the nested types. Можно определить вложенные типы без распространения параметры типа заключающих типов, путем создания кода в динамических сборках, или с помощью Ilasm.exe (ассемблер IL).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). Рассмотрим следующий код для ассемблера MSIL.Consider the following code for the MSIL assembler:

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

В этом примере не можно определить поля типа T или U в классе Innermost, так как таких параметров типа находятся вне области.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. Следующий код ассемблера определения вложенных классов, которые ведут себя так, определенных в C++, Visual Basic и C#.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> {  
        }  
    }  
}  

Можно использовать Ildasm.exe (дизассемблер IL) для проверки вложенные классы, определенные в языках высокого уровня и наблюдать за такая схема именования.You can use the Ildasm.exe (IL Disassembler) to examine nested classes defined in the high-level languages and observe this naming scheme.

Применяется к

Дополнительно