Type.GetType(),HashSet<T>和Assembly Qualification Type.GetType()方法返回一个给定类型名称的Type对象。HashSet<T>是一种集合类型,可用于存储唯一的元素。程序集限定指定要加载的程序集。

7

在解决问题“Error Loading ASP.Net Profile”时,我遇到了一个我不理解的Type.GetType(string typeName)行为。

当获取List<int>类型时,仅指定类型为

System.Collections.Generic.List`1[[System.Int32]]

是足够的。然而,对于HashSet<int>,我必须像这样指定完全限定的类型名称:

System.Collections.Generic.HashSet`1[[System.Int32]], System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

如果省略程序集、版本、区域性或公钥令牌中的任何一个,则无法解析该类型。

可复现代码:

// Returns expected type:
Type tListWorks = 
     Type.GetType("System.Collections.Generic.List`1[[System.Int32]]");

// Returns null:
Type tHashSetNull = 
     Type.GetType("System.Collections.Generic.HashSet`1[[System.Int32]]");

// Returns expected type:
Type tHashSetWorks = 
     Type.GetType("System.Collections.Generic.HashSet`1[[System.Int32]], System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");

// Returns null (omitted Culture):
Type tHashSetNoCultureFails = 
     Type.GetType("System.Collections.Generic.HashSet`1[[System.Int32]], System.Core, Version=4.0.0.0, PublicKeyToken=b77a5c561934e089");

问题

  • 为什么必须要完整地限定HashSet<T>而不需要限定List<T>
  • 考虑到版本必须要指定,如果.NET Runtime是3.5(第一个支持HashSet<T>的版本),或者更高版本如.NET 4.5,那该怎么办?如果运行时是其他完全不同的平台,比如Silverlight或Mono呢?

这个应该也可以工作(虽然我没有尝试过):System.Collections.Generic.HashSet1[[System.Int32]], System.Core`。 - Andrey Shchekin
@Andrey:这也是我的期望,但那并不起作用。 - Eric J.
这可能是相关的:https://dev59.com/znE95IYBdhLWcg3wUMHW#2367674 - Andrey Shchekin
我在F# Interactive中快速尝试了短版本(可行),以及PowerShell和Roslyn(不可行)。F# Interactive给了我Binding session to 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Core.dll'...。由于它显然无法解析字符串,我使用了一些反射器,并且如预期的那样,它安装了自定义的AppDomain.CurrentDomain.AssemblyResolve。因此,如果您使用允许较短名称的自定义程序集解析器,则应该可以指定较短的名称。 - Andrey Shchekin
1个回答

5

List<T>mscorelib中被定义,而HashSet<T>没有

根据文档

如果类型位于当前执行的程序集或Mscorlib.dll中,则提供其命名空间限定的类型名称即可。

对于您的第二个问题,如果向不在当前框架/配置文件中的程序集提供一个限定的类型名称,GetType将返回null。

需要所有程序集属性的原因在Type.GetType文档中有说明(由Jason Malinowski在评论中指出):

如果typeName包含命名空间但未包含程序集名称,则此方法仅搜索调用对象的程序集和Mscorlib.dll,顺序如上所述。 如果typeName使用部分或完整的程序集名称进行了完全限定,则此方法将在指定的程序集中进行搜索。 如果程序集具有强名称,则需要完整的程序集名称。


Eric是正确的。根据指定完全限定类型名称,仅使用程序集名称应该就足够了。不幸的是,我不确定为什么这里不起作用。 - Richard Szalay
2
阅读Type.GetType(string)的文档时,它指出:“如果typeName是使用部分或完整程序集名称进行了完全限定,则此方法将在指定的程序集中搜索。如果程序集具有强名称,则需要完整的程序集名称。” System.Core.dll具有强名称,因此可能无论如何都适用此规则。 - Jason Malinowski
@JasonMalinowski - 你应该将其作为单独的答案添加,因为它看起来像罪魁祸首。 - Richard Szalay
@RichardSzalay:我会在明天确认之前,不正式地说这是真的。 :-) - Jason Malinowski
@JasonMalinowski:我会把问题保持开放一段时间,以便您进行验证。当然,Richard也加一分。 - Eric J.
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接