反射与Type 类

2/29/2024 2:59:53 PM
261
0

System.Type

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

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

Type 是允许多个实现的抽象基类。 系统将始终提供派生类 RuntimeType。在反射中,对于每个对象,只会创建一个与之对应的类,并且支持比较操作。也就是说,通过 TypeRuntimeType,我们可以在运行时获取并操作类的相关信息,而且可以进行类之间的比较操作。

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

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

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

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

检索 Type 对象

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

  • 实例 Object.GetType 方法返回一个 Type 对象,该对象表示实例的类型。 由于所有托管类型派生自 Object, GetType 因此可以在任何类型的实例上调用该方法。
  • 静态 Type.GetType 方法返回一个 Type 对象,该对象表示由其完全限定名称指定的类型。
  • Module.GetTypeModule.GetTypesModule.FindTypes方法返回Type表示模块中定义的类型的对象。 第一种方法可用于获取模块中定义的所有公共类型和专用类型的对象数组 Type 。 (可以通过或方法或Type.Module属性获取实例。Assembly.GetModuleModuleAssembly.GetModules
  • 该 System.Reflection.Assembly 对象包含许多方法,用于检索程序集中定义的类,包括 Assembly.GetType, Assembly.GetTypes和 Assembly.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.GetType方法  <Type.GetType("System.String")>;

比较类型对象是否相等

唯一表示类型的对象是 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

搜索 name 区分大小写。 搜索包括公共静态和公共实例属性。

如果属性至少有一个访问器是公共的,则将其视为公共的反射。 否则,该属性被视为私有属性,并且必须使用BindingFlags.NonPublic | | BindingFlags.InstanceBindingFlags.Static(在 Visual Basic 中,将值组合在一Or起)来获取它。

如果当前 Type 表示构造的泛型类型,此方法将返回 PropertyInfo 由相应类型参数替换的类型参数。

如果当前 Type 表示泛型类型或泛型方法定义中的类型参数,此方法将搜索类约束的属性。

发生 AmbiguousMatchException 的情况包括:

  • 类型包含两个具有相同名称但不同数量的参数的索引属性。 若要解决歧义,请使用指定参数类型的方法的 GetProperty 重载。
  • 派生类型使用修饰符Shadows(在 Visual Basic 中)声明一个属性,new该属性隐藏具有相同名称的继承属性。 若要解决歧义,请使用 GetProperty(String, BindingFlags) 方法重载并添加 BindingFlags.DeclaredOnly 标志以将搜索限制为未继承的成员。

如果属性至少有一个访问器是公共的,则将其视为公共的反射。 否则,该属性被视为私有属性,并且必须使用BindingFlags.NonPublic | | BindingFlags.InstanceBindingFlags.Static(在 Visual Basic 中,将值组合在一Or起)来获取它。

以下 BindingFlags 筛选器标志可用于定义要在搜索中包含哪些属性:

  • 必须指定或BindingFlags.InstanceBindingFlags.Static用于获取返回结果。
  • 指定 BindingFlags.Public 在搜索中包含公共属性。
  • 指定 BindingFlags.NonPublic 在搜索中包含非公共属性(即专用属性、内部属性和受保护属性)。
  • 指定 BindingFlags.FlattenHierarchy 为包含 public 层次结构中的静态成员和 protected 静态成员; private 不包括继承类中的静态成员。

以下 BindingFlags 修饰符标志可用于更改搜索的工作原理:

  • BindingFlags.IgnoreCase 如果忽略 .,则 name
  • BindingFlags.DeclaredOnly 如果仅搜索声明 Type的属性,则不搜索只是继承的属性。

有关详细信息,请参阅System.Reflection.BindingFlags

如果当前 Type 表示构造的泛型类型,此方法将返回 PropertyInfo 由相应类型参数替换的类型参数。

如果当前 Type 表示泛型类型或泛型方法定义中的类型参数,此方法将搜索类约束的属性。

发生 AmbiguousMatchException 的情况包括:

  • 类型包含两个具有相同名称但不同数量的参数的索引属性。 若要解决歧义,请使用指定参数类型的方法的 GetProperty 重载。
  • 派生类型声明一个属性,该属性使用 new 修饰符(Shadows 在 Visual Basic 中)隐藏具有相同名称的继承属性。 若要解决歧义,请包括 BindingFlags.DeclaredOnly 将搜索限制为未继承的成员。

 

全部评论



提问