导出 (0) 打印
全部展开
此文章由人工翻译。 将光标移到文章的句子上,以查看原文。
译文
原文

Type.MakeGenericType 方法

更新:2010 年 6 月

替代由当前泛型类型定义的类型参数组成的类型数组的元素,并返回表示结果构造类型的 Type 对象。

命名空间:  System
程序集:  mscorlib(在 mscorlib.dll 中)

public virtual Type MakeGenericType(
	params Type[] typeArguments
)

参数

typeArguments
类型:System.Type[]
将代替当前泛型类型的类型参数的类型数组。

返回值

类型:System.Type
Type 表示的构造类型通过以下方式形成:用 typeArguments 的元素取代当前泛型类型的类型参数。

异常条件
InvalidOperationException

当前类型不表示泛型类型定义。 即,IsGenericTypeDefinition 返回 false

ArgumentNullException

typeArgumentsnull

- 或 -

typeArguments 的所有元素均为 null

ArgumentException

typeArguments 中元素的个数不等于当前泛型类型定义中类型参数的个数。

- 或 -

typeArguments 的所有元素都不满足为当前泛型类型的对应类型参数指定的约束。

- 或 -

typeArguments 包含一个元素,该元素是指针类型(Type.IsPointer 返回 true)、ByRef 类型(Type.IsByRef 返回 true)或 Void

NotSupportedException

基类不支持所调用的方法。 派生类必须提供实现。

MakeGenericType 方法允许编写向泛型类型定义的类型参数赋予特定类型的代码,从而创建表示特定构造类型的 Type 对象。 可以使用此 Type 对象来创建该构造类型的运行时实例。

使用 MakeGenericType 构造的类型可以是开放的,即它们的一些类型实参可以是封闭泛型方法或类型的类型形参。 您可以在发出动态程序集时使用这样的开放构造的类型。 例如,考虑下面的代码中的类 BaseDerived

public class Base<T, U> { }
public class Derived<V> : Base<int, V> { }

为了在动态程序集中生成 Derived,必须构造其基类型。 为此,可以使用泛型类型实参 Int32Derived 中的类型形参 V 来调用表示类 BaseType 对象上的 MakeGenericType 方法。 由于类型和泛型类型形参均由 Type 对象表示,因此可以向 MakeGenericType 方法传递同时包含这两者的数组。

注意说明:

诸如 Base<int, V> 的构造类型在发出代码时非常有用,但是您不能对此类型调用 MakeGenericType 方法,因为它不是泛型类型定义。 为了创建能够实例化的封闭构造的类型,可首先调用 GetGenericTypeDefinition 方法来获取表示泛型类型定义的 Type 对象,然后使用需要的类型实参调用 MakeGenericType

MakeGenericType 返回的 Type 对象与调用所产生构造类型的 GetType 方法(或从使用相同类型实参的相同泛型类型定义创建的任何构造类型的 GetType 方法)获得的 Type 相同。

注意说明:

泛型类型的数组本身不是泛型类型。 您不能对诸如 C<T>[](在 Visual Basic 中为 Dim ac() As C(Of T))的数组类型调用 MakeGenericType 若要基于 C<T>[] 构造封闭泛型类型,需要调用 GetElementType 以获取泛型类型定义 C<T>,对该泛型类型定义调用 MakeGenericType 以创建构造类型,最后对该构造类型调用 MakeArrayType 方法以创建数组类型。 对于指针类型和 ref 类型(在 Visual Basic 中为 ByRef)也是如此。

有关泛型反射中使用的术语的固定条件列表,请参见 IsGenericType 属性备注。

嵌套类型

如果泛型类型是使用 C#、C++ 或 Visual Basic 定义的,那么其嵌套类型都是泛型。 即使嵌套类型没有自己的类型参数也是如此,因为所有三种语言都在嵌套类型的类型参数列表中包括了封闭类型的类型参数。 请考虑下面的类:

public class Outermost<T>
{
    public class Inner<U>
    {
        public class Innermost1<V> {}
        public class Innermost2 {}
    }
}

嵌套类 Inner 的类型参数列表有两个类型参数 TU,其中第一个是其封闭类的类型参数。 类似地,嵌套类 Innermost1 的类型参数列表有三个类型参数 TUV,其中 TU 来自其封闭类。 嵌套类 Innermost2 有两个类型参数 TU,它们都来自其封闭类。

如果封闭类型的参数列表有多个类型参数,则所有类型参数都按顺序包括在嵌套类型的类型参数列表中。

为了从嵌套的类型的泛型类型定义来构造泛型类型,可以使用通过串联所有封闭类型的类型实参数组(从最外层的泛型类型开始,到嵌套的类型本身的类型实参数组结束 — 如果它有自己的类型参数的话)形成的数组来调用 MakeGenericType 方法。 若要创建 Innermost1 的实例,请对包含三个类型(这些类型要分配给 T、U 和 V)的数组调用 MakeGenericType 方法。 若要创建 Innermost2 的实例,请对包含两个类型(这些类型要分配给 T 和 U)的数组调用 MakeGenericType 方法。

语言以此方式传播封闭类型的类型参数,所以,您可以使用封闭类型的类型参数来定义嵌套类型的字段。 否则,类型参数将不会在嵌套类型体的范围内。 通过在动态程序集中发出代码或使用 Microsoft 中间语言 (MSIL) 汇编程序,无需传播封闭类型的类型参数即可定义嵌套类型。 考虑 MSIL 汇编程序的以下代码:

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

在此例中,无法在类 Innermost 中定义 TU 类型的字段,因为这些类型参数不在范围内。 下面的汇编程序代码定义与在 C++、Visual Basic 和 C# 中定义时具有相同表现的嵌套类:

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

可以使用 MSIL 反汇编程序检验使用高级语言定义的嵌套类,并遵循此命名方案。 有关反汇编程序的信息,请参见完整的 .NET Framework 文档中的 MSIL 反汇编程序 (Ildasm.exe)

下面的示例使用 MakeGenericType 方法基于 Dictionary<TKey, TValue> 类型的泛型类型定义创建构造类型。 构造类型表示具有字符串键的 Test 对象的 Dictionary<TKey, TValue>

注意说明:

若要运行此示例,请参见生成使用 Demo 方法和 TextBlock 控件的示例


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

public class Example
{
   public static void Demo(System.Windows.Controls.TextBlock outputBlock)
   {
      outputBlock.Text += "\r\n--- Create a constructed type from the generic Dictionary type." + "\n";

      // 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(outputBlock, 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 Example.
      Type[] typeArgs = { typeof(string), typeof(Example) };

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

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

      Type t = typeof(Dictionary<String, Example>);
      outputBlock.Text += String.Format("\tAre the constructed types equal? {0}", t == constructed) + "\n";
      outputBlock.Text += String.Format("\tAre the generic types equal? {0}",
          t.GetGenericTypeDefinition() == generic) + "\n";
   }

   private static void DisplayTypeInfo(System.Windows.Controls.TextBlock outputBlock, Type t)
   {
      outputBlock.Text += String.Format("\r\n{0}", t) + "\n";

      outputBlock.Text += String.Format("\tIs this a generic type definition? {0}",
          t.IsGenericTypeDefinition) + "\n";

      outputBlock.Text += String.Format("\tIs it a generic type? {0}",
          t.IsGenericType) + "\n";

      Type[] typeArguments = t.GetGenericArguments();
      outputBlock.Text += String.Format("\tList type arguments ({0}):", typeArguments.Length) + "\n";
      foreach (Type tParam in typeArguments)
      {
         outputBlock.Text += String.Format("\t\t{0}", tParam) + "\n";
      }
   }
}

/* 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
 */


Silverlight

受以下版本支持:5、4、3

Silverlight for Windows Phone

受以下版本支持:Windows Phone OS 7.1、Windows Phone OS 7.0

XNA Framework

受以下版本支持:Xbox 360、Windows Phone OS 7.0

有关 Silverlight 支持的操作系统和浏览器的列表,请参见 支持的操作系统和浏览器

日期

修订历史记录

原因

2010 年 6 月

添加了 ArgumentException 异常丢失的原因。

客户反馈意见。

社区附加资源

添加
显示:
© 2015 Microsoft