System.Type.GetType 方法

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

GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean, Boolean)使用方法重载及其关联的重载(GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>)GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean))将方法的默认实现替换为更灵活的实现GetType。 通过提供自己的方法来解析类型名称和包含它们的程序集的名称,可以执行以下操作:

  • 控制从中加载类型的程序集的版本。
  • 提供另一个位置来查找不包含程序集名称的类型名称。
  • 使用部分程序集名称加载程序集。
  • 返回公共语言运行时(CLR)未创建的子类 System.Type

例如,在版本容错序列化中,此方法允许使用部分名称搜索“最适合”程序集。 该方法的其他重载 GetType 需要程序集限定的类型名称,其中包括版本号。

类型系统的备用实现可能需要返回 CLR 未创建的子类 System.Type ;该方法的其他重载 GetType 返回的所有类型都是运行时类型。

使用注意事项

此方法重载及其关联的重载将分析 typeName 为类型的名称和程序集的名称,然后解析名称。 程序集名称的解析发生在类型名称解析之前,因为必须在程序集的上下文中解析类型名称。

注意

如果不熟悉程序集限定类型名称的概念,请参阅该 AssemblyQualifiedName 属性。

如果 typeName 不是程序集限定的名称,则跳过程序集解析。 可以在mscorlib.dll/System.Private.CoreLib.dll或当前正在执行的程序集的上下文中解析非限定类型名称,或者可以选择在 typeResolver 参数中提供程序集。 在混合名称解析部分中,包括或省略不同类型名称解析的程序集名称的效果显示为表

常规用法说明:

  • 不要将 assemblyResolver 方法传递给或 typeResolver 来自未知或不受信任的调用方的方法。 仅使用你提供或者熟悉的方法。

    注意

    使用未知或不受信任的调用方的方法可能会导致恶意代码特权提升。

  • 如果省略 assemblyResolver 和/或 typeResolver 参数,则参数的值 throwOnError 将传递给执行默认解析的方法。

  • 如果是throwOnError,此方法将TypeLoadException引发返回null时间typeResolver,返回FileNotFoundException时间assemblyResolvernulltrue

  • 此方法不捕获由 assemblyResolvertypeResolver引发的异常。 你负责解析程序方法引发的任何异常。

解析程序集

该方法 assemblyResolver 接收一个 AssemblyName 对象,该对象是通过分析包含在 typeName其中的字符串程序集名称生成的。 如果 typeName 不包含程序集名称, assemblyResolver 则不调用并 null 传递给 typeResolver

如果未 assemblyResolver 提供,则使用标准程序集探测来查找程序集。 如果 assemblyResolver 已提供,则 GetType 该方法不执行标准探测;在这种情况下,必须确保 assemblyResolver 可以处理传递给它的所有程序集。

如果无法解析程序集,该方法 assemblyResolver 应返回 null 。 如果返回,则不调用,不会进一步处理;此外,如果是throwOnErrortrue,则会引发 aFileNotFoundExceptiontypeResolvernullassemblyResolver

AssemblyName如果传递给assemblyResolver的是部分名称,则其一个或多个部分为 null。 例如,如果它没有版本,则 Version 属性为 null. Version如果属性、CultureInfo属性和GetPublicKeyToken方法全部返回null,则只提供程序集的简单名称。 该方法 assemblyResolver 可以使用或忽略程序集名称的所有部分。

不同程序集解析选项的效果显示为混合名称解析部分中的表,用于简单类型名称和程序集限定的类型名称。

解析类型

如果未 typeName 指定程序集名称, typeResolver 则始终调用。 如果 typeName 指定程序集名称, typeResolver 则仅在成功解析程序集名称时调用。 如果 assemblyResolver 或标准程序集探测返回 nulltypeResolver 则不调用。

该方法 typeResolver 接收三个参数:

  • 要搜索的程序集,或者 null 不包含 typeName 程序集名称。
  • 类型的简单名称。 对于嵌套类型,这是最外部的包含类型。 对于泛型类型,这是泛型类型的简单名称。
  • 一个布尔值,表示 true 要忽略类型名称大小写。

实现确定使用这些参数的方式。 typeResolver如果方法无法解析类型,则该方法应返回null。 如果返回并且是,则此重载GetType将引发 aTypeLoadExceptiontruethrowOnErrornulltypeResolver

对于简单和程序集限定的类型名称,不同类型解析选项的效果显示为混合名称解析部分中的表

解析嵌套类型

如果 typeName 为嵌套类型,则仅将最外层包含类型的名称传递给 typeResolver。 返回此类型时 typeResolver ,该方法 GetNestedType 以递归方式调用,直到解析最内部的嵌套类型。

解析泛型类型

GetType 递归方式调用它以解析泛型类型:首先解析泛型类型本身,然后解析其类型参数。 如果类型参数是泛型的, GetType 则以递归方式调用以解析其类型参数,依此类推。

你提供的组合assemblyResolvertypeResolver必须能够解析此递归的所有级别。 例如,假设你提供一个 assemblyResolver 控制加载的 MyAssembly控件。 假设你想要解析泛型类型 Dictionary<string, MyType>Dictionary(Of String, MyType) 在 Visual Basic 中)。 可以传递以下泛型类型名称:

"System.Collections.Generic.Dictionary`2[System.String,[MyNamespace.MyType, MyAssembly]]"

请注意, MyType 这是唯一的程序集限定类型参数。 和String类的名称Dictionary<TKey,TValue>不是程序集限定的。 你必须typeResolver能够处理程序集,或者null,因为它将接收并String接收nullDictionary<TKey,TValue>。 它可以通过调用采用字符串的方法的 GetType 重载来处理这种情况,因为两个未限定的类型名称都在mscorlib.dll/System.Private.CoreLib.dll中:

Type t = Type.GetType(test,
                      (aName) => aName.Name == "MyAssembly" ?
                          Assembly.LoadFrom(@".\MyPath\v5.0\MyAssembly.dll") : null,
                      (assem, name, ignore) => assem == null ?
                          Type.GetType(name, false, ignore) :
                              assem.GetType(name, false, ignore)
                     );
let t =
    Type.GetType(test,
        (fun aName ->
            if aName.Name = "MyAssembly" then
                Assembly.LoadFrom @".\MyPath\v5.0\MyAssembly.dll"
            else null),
        fun assem name ignr ->
            if assem = null then
                Type.GetType(name, false, ignr)
            else
                assem.GetType(name, false, ignr))

不会 assemblyResolver 为字典类型和字符串类型调用该方法,因为这些类型名称不是程序集限定的。

现在假设第System.String一个泛型参数类型来自YourTypeYourAssembly

"System.Collections.Generic.Dictionary`2[[YourNamespace.YourType, YourAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null], [MyNamespace.MyType, MyAssembly]]"

由于此程序集既不是mscorlib.dll/System.Private.CoreLib.dll也不是当前正在执行的程序集,因此不能在没有程序集限定名称的情况下解析 YourType 。 由于将以递归方式调用, assemblyResolve 因此它必须能够处理这种情况。 它现在使用提供AssemblyName的对象执行程序集加载,而不是为程序集MyAssembly返回null

Type t2 = Type.GetType(test,
                       (aName) => aName.Name == "MyAssembly" ?
                           Assembly.LoadFrom(@".\MyPath\v5.0\MyAssembly.dll") :
                           Assembly.Load(aName),
                       (assem, name, ignore) => assem == null ?
                           Type.GetType(name, false, ignore) :
                               assem.GetType(name, false, ignore), true
                      );
let t2 =
    Type.GetType(test,
        (fun aName ->
            if aName.Name = "MyAssembly" then
                Assembly.LoadFrom @".\MyPath\v5.0\MyAssembly.dll"
            else Assembly.Load aName),
        (fun assem name ignr ->
            if assem = null then
                Type.GetType(name, false, ignr)
            else
                assem.GetType(name, false, ignr)), true)

解析具有特殊字符的类型名称

某些字符在程序集限定名称中具有特殊含义。 如果简单类型名称包含这些字符,则当简单名称是程序集限定名称的一部分时,这些字符会导致分析错误。 若要避免分析错误,必须使用反斜杠转义特殊字符,然后才能将程序集限定名称传递给 GetType 方法。 例如,如果命名Strange]Type了类型,则必须在方括号前面添加转义字符,如下所示: Strange\]Type

注意

不能在 Visual Basic 或 C# 中创建具有此类特殊字符的名称,但可以使用公共中间语言(CIL)或发出动态程序集来创建。

下表显示了类型名称的特殊字符。

字符 含义
, (逗号) 程序集限定名称的分隔符。
[] (方括号) 作为后缀对,指示数组类型;作为分隔符对,将泛型参数列表和程序集限定的名称括起来。
&(与号) 作为后缀,指示类型是引用类型。
* (星号) 作为后缀,指示类型是指针类型。
+ (加) 嵌套类型的分隔符。
\ (反斜杠) 转义字符。

返回正确转义字符串等 AssemblyQualifiedName 属性。 必须将正确转义的字符串传递给 GetType 该方法。 反过来,该方法会将 GetType 正确转义的名称 typeResolver 传递给默认类型解析方法以及传递给默认类型解析方法。 如果需要将名称与未转义的名称 typeResolver进行比较,则必须删除转义字符。

混合名称解析

下表汇总了类型名称和程序集名称typeName的所有组合之间的typeResolverassemblyResolver交互以及默认名称解析:

类型名称的内容 程序集解析程序方法 类型解析程序方法 Result
type、 assembly Null Null 等效于调用 Type.GetType(String, Boolean, Boolean) 方法重载。
type、 assembly 提供的 Null assemblyResolver 如果程序集无法解析程序集,则返回 null 该程序集。 如果解析程序集,则 Assembly.GetType(String, Boolean, Boolean) 方法重载用于从程序集加载类型;否则,不会尝试解析该类型。
type、 assembly Null 提供的 等效于将程序集名称转换为对象 AssemblyName 并调用 Assembly.Load(AssemblyName) 方法重载来获取程序集。 如果已解析程序集,则会传递给 typeResolver该程序集;否则 typeResolver ,不会调用该程序集,并且不会进一步尝试解析类型。
type、 assembly 提供的 提供的 assemblyResolver 如果程序集无法解析程序集,则返回 null 该程序集。 如果已解析程序集,则会传递给 typeResolver该程序集;否则 typeResolver ,不会调用该程序集,并且不会进一步尝试解析类型。
type null,提供 Null 等效于调用 Type.GetType(String, Boolean, Boolean) 方法重载。 由于未提供程序集名称,因此仅搜索mscorlib.dll/System.Private.CoreLib.dll和当前正在执行的程序集。 如果 assemblyResolver 已提供,则忽略它。
type null,提供 提供的 typeResolver 调用 并 null 传递程序集。 typeResolver 可以从任何程序集提供类型,包括它为此加载的程序集。 如果 assemblyResolver 已提供,则忽略它。
assembly null,提供 null,提供 引发 A FileLoadException ,因为程序集名称被分析为程序集限定的类型名称。 这会导致程序集名称无效。