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 返回 falseThat is, IsGenericTypeDefinition returns false.

typeArgumentsnulltypeArguments is null.

- 或 --or- typeArguments 的任意元素为 nullAny 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)、by-ref 类型(IsByRef 返回 true)或 VoidtypeArguments 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. 例如,考虑类BaseDerived在下面的代码。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,并使用类型参数VDerivedTo 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具有两个类型参数,TU,其中第一个为其封闭类的类型参数。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有三个类型参数, TU,和V,与TU来自其封闭类。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具有两个类型参数,TU,它们都来自其封闭类。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 {  
        }  
    }  
}  

在此示例中,它不能定义类型的字段TU类中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.

适用于

另请参阅