System.Type 类

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

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

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

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

注释

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

注释

派生类可以访问调用代码基类的受保护成员。 此外,允许访问调用代码程序集的程序集成员。 通常情况下,如果在早期绑定代码中获得访问权限,那么在后期绑定代码中也会获准访问。

注释

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

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

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

  • 课程
  • 值类型
  • 数组
  • 接口
  • 枚举
  • 代表
  • 构造的泛型类型和泛型类型定义
  • 构造泛型类型、泛型类型定义和泛型方法定义的类型变量和类型参数

检索类型对象

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

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

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

    object[] values = { "word", true, 120, 136.34, 'a' };
    foreach (var value in values)
        Console.WriteLine($"{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
    
    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.GetTypesModule.GetTypeModule.FindTypes方法返回Type对象,这些对象表示模块中定义的类型。 第一种方法可用于获取模块中定义的所有公共类型和专用类型的对象数组 Type 。 (可以通过Module方法、Assembly.GetModule方法或Assembly.GetModules属性获取Type.Module的实例。)

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

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

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

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

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

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

  • GetTypeFromHandle 方法是为了实现互操作性而提供的。 它返回一个 Type 对象,该对象表示类句柄指定的类型。

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

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

  • MakeArrayTypeMakePointerTypeMakeByRefType方法返回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: {Object.ReferenceEquals(t, number2.GetType())}");
Console.WriteLine($"Type of number1 and number3 are equal: {Object.ReferenceEquals(t, number3.GetType())}");
Console.WriteLine($"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
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