开发者

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

开发者 https://www.devze.com 2022-12-22 04:23 出处:网络
In numerous places do I encounter partially qualified type names of the form FullTypeName, AssemblyName, i.e. like Type.AssemblyQualifiedName only without the version, culture and publicKeyTo开发者_C百

In numerous places do I encounter partially qualified type names of the form FullTypeName, AssemblyName, i.e. like Type.AssemblyQualifiedName only without the version, culture and publicKeyTo开发者_C百科ken qualifiers.

My question is how can one convert it to the respective Type in a minimum of effort? I thought that Type.GetType does the job, but alas, it does not. The following code, for instance, returns null:

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

Of course, if I specify the fully qualified name it does work:

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

Thanks a lot.


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");


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.


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")


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.


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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号