How Type.GetType works when given partially qualified type name?

前端 未结 5 928
谎友^
谎友^ 2020-11-30 13:50

In numerous places do I encounter partially qualified type names of the form FullTypeName, AssemblyName, i.e. like Type.AssemblyQualifiedName only

相关标签:
5条回答
  • 2020-11-30 14:16

    Code working with the short form is:

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

    but LoadWithPartialName is deprecated, so I guess you should stick with the long form.

    0 讨论(0)
  • 2020-11-30 14:17

    True, Type.GetType(string) does require an AssemblyQualifiedName. This can be in many forms:

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

    The following are also valid 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
    

    For a signed assembly, the minimum required for a FullyQualifiedAssemblyName is:

    MyNS.MyType, MyAssembly, PublicKeyToken=XXXXXXXXXX
    

    For an unsigned assembly, the minimum required for a FullyQualifiedAssemblyName is:

    MyNS.MyType, MyAssembly
    

    No need for all the "hand waving" going on in the code snippets others have provided. Ensure that your type names are set up properly and you can access your types (and load assemblies dynamically) with a high degree of flexibility. I do this regularly.

    In OP's example using:

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

    The reason for the failure was the absence of the PublicKeyToken. The .Net FW assemblies are all signed and therefore require the PublicKeyToken to resolve the Assembly name. The following would work:

    Type.GetType("System.Net.Sockets.SocketException, System, PublicKeyToken=b77a5c561934e089")
    
    0 讨论(0)
  • 2020-11-30 14:21

    Having just gone through a similar issue with some legacy code, I don't think that the first statement in the accepted answer is correct. It doesn't matter whether or not the assembly is already loaded.

    According to the documentation, Type.GetType(string) requires an AssemblyQualifiedName, unless the type in question is in the currently executing assembly or in mscorlib, in which case the namespace-qualified type name is all that is required.

    Note that an AssemblyQualifiedName includes the full DisplayName of the type's assembly (with version, culture and public key token).

    The short version won't work unless you intercept the failed type load with a custom AssemblyResolver (which was actually the case with my issue, masking another problem).

    0 讨论(0)
  • 2020-11-30 14:24

    If the DLL it's in isn't already loaded into the application domain (e.g. you used it), you need the full path like this, if it's already loaded, it can find it with the shorter version.

    To answer your question: the second version always works, stick with it and you have one way to worry about.

    0 讨论(0)
  • 2020-11-30 14:27

    If the assembly has been loaded in the current domain then the code below usually works:

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

    You can use it like so:

    Type t = GetTypeEx("System.Net.Sockets.SocketException");
    
    0 讨论(0)
提交回复
热议问题