为什么 Assembly.GetType() 不适用于泛型类型实例?

Hen*_*erg 2 c# generics reflection

我在单独的程序集中有一个通用类:

class MyGenericClass<T> { }
Run Code Online (Sandbox Code Playgroud)

在另一个程序集中,我尝试这样做:

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]");
Run Code Online (Sandbox Code Playgroud)

现在,第一次调用GetType将返回泛型类型,但第二次调用将返回 null。

我测试了对以下类型执行相同的操作List<>

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]");
Run Code Online (Sandbox Code Playgroud)

现在,这一次有效了。返回的类型List<String>。这让我完全困惑。

为什么GetType()在使用类型参数调用时无法获取我的类型,而在使用相同类型参数调用时[System.String]能够获取类型?List

还有其他方法可以获取我的类型吗?我知道我可以解析类型名,提取部分MyClassLibrary.MyGenericClass'1[System.String],然后根据这些类型实例化通用类型,但我可能会在此过程中搞砸一些事情,所以我正在寻找一种更简单,可靠的内置方法来获取这个类型的对象。

mm8*_*mm8 5

该字符串应包含其他程序集中类型的完全限定名称:

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

您可能需要考虑实现一个为您提供类型的自定义方法:

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;
}
Run Code Online (Sandbox Code Playgroud)