Henrik Berg
Henrik Berg

Reputation: 549

Why doesn't Assembly.GetType() work for generic type instances?

I have a generic class in a separate assembly:

class MyGenericClass<T> { }

In another assembly, I try to do this:

var assembly = System.Reflection.Assembly.LoadFrom(@"C:\path-to\MyClassLibrary.dll");  
var t1 = assembly.GetType("MyClassLibrary.MyGenericClass`1");
var t2 = assembly.GetType("MyClassLibrary.MyGenericClass`1[System.String]");

Now, the first call to GetType will return a generic type, but the second will return null.

I tested doing the same with the List<> type:

var assembly2 = System.Reflection.Assembly.LoadFrom(@"C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll");
var t3 = assembly2.GetType("System.Collections.Generic.List`1[System.String]");

Now, this time it works. The type of List<String> is returned. Which leaves me utterly confused.

Why will GetType() not get my type when called with a type parameter [System.String], when it is able to get the List type when called with the same type parameter?

And is there any other way to get hold of my type? I know I can parse the typename, to extract the parts MyClassLibrary.MyGenericClass'1 and [System.String], and then instantiate the generic type based on these types, but I would probably mess something up along the way, so I was looking for a simpler, solid, built-in way to get this type object.

Upvotes: 2

Views: 1120

Answers (1)

mm8
mm8

Reputation: 169240

The string should include the fully qualified named of the type in the other assembly:

var t2 = assembly.GetType("MyClassLibrary.MyGenericClass`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]");

You might want to consider implementing a custom method that gives you the type:

static Type GetType(Assembly assembly, string typeName)
{
    Type type = assembly.GetType(typeName);
    if (type == null)
    {
        int index = typeName.IndexOf("`1");
        if (index != -1)
        {
            index += 2;
            ReadOnlySpan<char> span = typeName.AsSpan();
            type = Type.GetType(span.Slice(0, index).ToString());
            return type.MakeGenericType(Type.GetType(span.Slice(index + 1, span.Length - index - 2).ToString()));
        }
    }
    return type;
}

Upvotes: 5

Related Questions