给定部分限定类型名称时,Type.GetType如何工作?

时间:2010-03-02 23:17:17

标签: .net types

在很多地方,我遇到了FullTypeName, AssemblyName形式的部分限定类型名称,即仅与Type.AssemblyQualifiedName类似,但没有版本,culture和publicKeyToken限定符。

我的问题是如何以最小的努力将其转换为相应的Type?我认为Type.GetType完成了这项工作,但唉,事实并非如此。例如,以下代码返回null

Type.GetType("System.Net.Sockets.SocketException, System");

当然,如果我指定完全限定名称,它确实有效:

Type.GetType("System.Net.Sockets.SocketException, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");

非常感谢。

5 个答案:

答案 0 :(得分:31)

如果已在当前域中加载程序集,则下面的代码通常有效:

public static Type GetTypeEx(string fullTypeName)
{
    return Type.GetType(fullTypeName) ??
           AppDomain.CurrentDomain.GetAssemblies()
                    .Select(a => a.GetType(fullTypeName))
                    .FirstOrDefault(t => t != null);
}

您可以像这样使用它:

Type t = GetTypeEx("System.Net.Sockets.SocketException");

答案 1 :(得分:8)

如果它所在的DLL尚未加载到应用程序域中(例如,您使用过它),则需要这样的完整路径,如果已加载,则可以使用较短的版本找到它。

回答你的问题:第二个版本总是有效,坚持下去,你有一种方法可以担心。

答案 2 :(得分:2)

使用简短形式的代码是:

    Assembly a = Assembly.LoadWithPartialName(assemblyName);
    Type t = a.GetType(typeName);

但不推荐使用LoadWithPartialName,所以我猜你应该坚持使用长格式。

答案 3 :(得分:2)

刚刚遇到类似遗留代码的问题,我不认为接受的答案中的第一个陈述是正确的。无论装配是否已装载都无关紧要。

根据文档,Type.GetType(string)需要AssemblyQualifiedName,除非有问题的类型在当前正在执行的程序集中或在mscorlib中,在这种情况下,名称空间限定的类型名称就是所需的全部内容

请注意,AssemblyQualifiedName包含类型程序集的完整DisplayName(包含版本,区域性和公钥标记)。

除非您使用自定义AssemblyResolver拦截失败的类型加载,否则短版本将无效(实际情况就是我的问题,掩盖了另一个问题)。

答案 4 :(得分:1)

True,Type.GetType(string)确实需要AssemblyQualifiedName。这可以有多种形式:

MyNS.MyType, MyAssembly, Version=x.x.x.x, Culture=xxx, PublicKeyToken=XXXXXXXXXX

以下也是有效的AssemblyQualifiedNames:

MyNS.MyType, MyAssembly, Version=x.x, Culture=xxx, PublicKeyToken=XXXXXXXXXX
MyNS.MyType, MyAssembly, Culture=xxx, PublicKeyToken=XXXXXXXXXX
MyNS.MyType, MyAssembly, PublicKeyToken=XXXXXXXXXX
MyNS.MyType, MyAssembly

对于已签名的程序集,FullyQualifiedAssemblyName所需的最小值为:

MyNS.MyType, MyAssembly, PublicKeyToken=XXXXXXXXXX

对于unsigned程序集,FullyQualifiedAssemblyName所需的最小值为:

MyNS.MyType, MyAssembly

不需要所有的挥动"继续其他人提供的代码片段。确保您的类型名称设置正确,并且您可以高度灵活地访问类型(并动态加载程序集)。我经常这样做。

在OP的例子中使用:

Type.GetType("System.Net.Sockets.SocketException, System")

失败的原因是没有PublicKeyToken。 .Net FW程序集都已签名,因此需要PublicKeyToken来解析程序集名称。以下方法可行:

Type.GetType("System.Net.Sockets.SocketException, System, PublicKeyToken=b77a5c561934e089")