System.Type 类

本文提供了此 API 参考文档的补充说明。

Type 类是功能的根 System.Reflection 目录,是访问元数据的主要方法。 使用成员 Type 获取有关类型声明、类型成员的信息(如类的构造函数、方法、字段、属性和事件),以及在其中部署类的模块和程序集。

代码无需任何权限即可使用反射来获取有关类型及其成员的信息,而不考虑其访问级别。 代码无需任何权限即可使用反射来访问公共成员,或者访问级别会使公共成员在正常编译期间可见的其他成员。 但是,为了让代码使用反射来访问通常不可访问的成员,例如私有方法或内部方法,或者类未继承的受保护字段,代码必须具有 ReflectionPermission。 请参阅有关反应的安全注意事项。

Type 是允许多个实现的抽象基类。 系统将始终提供派生类 RuntimeType。 在反射中,从单词运行时开始的所有类仅在系统中为每个对象创建一次,并支持比较操作。

注意

在多线程方案中,不要锁定 Type 对象以同步对 static 数据的访问。 没有控制权的其他代码也可能锁定类类型。 这可能会导致死锁。 而是通过锁定专用 static 对象来同步对静态数据的访问。

注意

派生类可以访问调用代码基类的受保护成员。 此外,允许访问调用代码程序集的程序集成员。 作为规则,如果在早期绑定代码中允许访问,则还允许在后期绑定代码中访问。

注意

扩展其他接口的接口不会继承扩展接口中定义的方法。

Type 对象表示的类型是什么?

此类是线程安全的;多个线程可以同时从此类型的实例中读取。 类的 Type 实例可以表示以下任一类型:

  • 值类型
  • 数组
  • 接口
  • 枚举
  • 委托
  • 构造的泛型类型和泛型类型定义
  • 构造泛型类型、泛型类型定义和泛型方法定义的类型参数和类型参数

检索 Type 对象

Type可以通过以下方式获取与特定类型关联的对象:

  • 实例 Object.GetType 方法返回一个 Type 对象,该对象表示实例的类型。 由于所有托管类型派生自 ObjectGetType 因此可以在任何类型的实例上调用该方法。

    下面的示例调用 Object.GetType 该方法来确定对象数组中每个对象的运行时类型。

    object[] values = { "word", true, 120, 136.34, 'a' };
    foreach (var value in values)
        Console.WriteLine("{0} - type {1}", value,
                          value.GetType().Name);
    
    // The example displays the following output:
    //       word - type String
    //       True - type Boolean
    //       120 - type Int32
    //       136.34 - type Double
    //       a - type Char
    
    let values: obj[] = [| "word"; true; 120; 136.34; 'a' |]
    for value in values do
       printfn $"{value} - type {value.GetType().Name}"
    
    // The example displays the following output:
    //       word - type String
    //       True - type Boolean
    //       120 - type Int32
    //       136.34 - type Double
    //       a - type Char
    
    Module Example1
       Public Sub Main()
          Dim values() As Object = { "word", True, 120, 136.34, "a"c }
          For Each value In values
             Console.WriteLine("{0} - type {1}", value, 
                               value.GetType().Name)
          Next
       End Sub
    End Module
    ' The example displays the following output:
    '       word - type String
    '       True - type Boolean
    '       120 - type Int32
    '       136.34 - type Double
    '       a - type Char
    
  • 静态 Type.GetType 方法返回一个 Type 对象,该对象表示由其完全限定名称指定的类型。

  • Module.GetTypeModule.GetTypesModule.FindTypes方法返回Type表示模块中定义的类型的对象。 第一种方法可用于获取模块中定义的所有公共类型和专用类型的对象数组 Type 。 (可以通过或方法或Type.Module属性获取实例。Assembly.GetModuleModuleAssembly.GetModules

  • System.Reflection.Assembly 对象包含许多方法,用于检索程序集中定义的类,包括 Assembly.GetTypeAssembly.GetTypesAssembly.GetExportedTypes

  • 该方法 FindInterfaces 返回类型支持的接口类型的筛选列表。

  • 该方法 GetElementType 返回一个 Type 表示元素的对象。

  • GetInterfacesGetInterface方法返回Type表示类型支持的接口类型的对象。

  • 该方法 GetTypeArray 返回一个 Type 对象数组,该数组表示由任意对象集指定的类型。 这些对象是用类型的 Object数组指定的。

  • GetTypeFromProgID提供 COM 互操作性的方法和GetTypeFromCLSID方法。 它们返回一个 Type 对象,该对象表示由 ProgID or CLSID指定的类型。

  • 此方法 GetTypeFromHandle 用于互操作性。 它返回一个 Type 对象,该对象表示类句柄指定的类型。

  • C# typeof 运算符、C++ typeid 运算符和 Visual Basic GetType 运算符获取 Type 类型的对象。

  • 该方法MakeGenericType返回一个Type对象,该对象表示构造的泛型类型,如果其属性返回true,则返回ContainsGenericParameters一个打开的构造类型,否则返回一个封闭的构造类型。 仅当泛型类型已关闭时,才能实例化泛型类型。

  • MakePointerTypeMakeArrayTypeMakeByRefType方法返回Type的对象分别表示指定类型的数组、指向指定类型的指针以及引用参数的类型(ref在 C#中,在 F# ByRef 中的“byref”,在 Visual Basic 中)。

比较类型对象是否相等

表示类型的对象是唯一 Type 的;也就是说,如果 Type 两个对象引用表示同一类型,则两个对象引用引用同一对象。 这允许使用引用相等性比较 Type 对象。 下面的示例比较 Type 表示多个整数值的对象,以确定它们是否属于同一类型。

long number1 = 1635429;
int number2 = 16203;
double number3 = 1639.41;
long number4 = 193685412;

// Get the type of number1.
Type t = number1.GetType();

// Compare types of all objects with number1.
Console.WriteLine("Type of number1 and number2 are equal: {0}",
                  Object.ReferenceEquals(t, number2.GetType()));
Console.WriteLine("Type of number1 and number3 are equal: {0}",
                  Object.ReferenceEquals(t, number3.GetType()));
Console.WriteLine("Type of number1 and number4 are equal: {0}",
                  Object.ReferenceEquals(t, number4.GetType()));

// The example displays the following output:
//       Type of number1 and number2 are equal: False
//       Type of number1 and number3 are equal: False
//       Type of number1 and number4 are equal: True
let number1 = 1635429L
let number2 = 16203
let number3 = 1639.41
let number4 = 193685412L

// Get the type of number1.
let t = number1.GetType()

// Compare types of all objects with number1.
printfn $"Type of number1 and number2 are equal: {Object.ReferenceEquals(t, number2.GetType())}"
printfn $"Type of number1 and number3 are equal: {Object.ReferenceEquals(t, number3.GetType())}"
printfn $"Type of number1 and number4 are equal: {Object.ReferenceEquals(t, number4.GetType())}"

// The example displays the following output:
//       Type of number1 and number2 are equal: False
//       Type of number1 and number3 are equal: False
//       Type of number1 and number4 are equal: True
Module Example
   Public Sub Main()
      Dim number1 As Long = 1635429
      Dim number2 As Integer = 16203
      Dim number3 As Double = 1639.41
      Dim number4 As Long = 193685412
      
      ' Get the type of number1.
      Dim t As Type = number1.GetType()
      
      ' Compare types of all objects with number1.
      Console.WriteLine("Type of number1 and number2 are equal: {0}",
                        Object.ReferenceEquals(t, number2.GetType()))
      Console.WriteLine("Type of number1 and number3 are equal: {0}",
                        Object.ReferenceEquals(t, number3.GetType()))
      Console.WriteLine("Type of number1 and number4 are equal: {0}",
                        Object.ReferenceEquals(t, number4.GetType()))
   End Sub
End Module
' The example displays the following output:
'       Type of number1 and number2 are equal: False
'       Type of number1 and number3 are equal: False
'       Type of number1 and number4 are equal: True