使用Assembly.LoadFrom加载泛型类型

时间:2012-08-20 10:43:40

标签: c# generics late-binding

请参阅Jon Skeet的回答:Pass An Instantiated System.Type as a Type Parameter for a Generic Class

我需要根据泛型类型的名称加载Generic类型,以及作为泛型的type参数的类型的名称。所以从Jon的例子我会:

string genName = "MyNamespace.Generic";
string itemName = "System.String";

我有以下代码,它将根据类型名称和完全对齐的程序集名称/路径加载类型。它适用于“简单类型”

public Type GetTypeOf(string assemblyPath, string className)
{
    var asmbly = System.Reflection.Assembly.LoadFrom(assemblyPath); //open assembly
    return asmbly.GetType(className, true, true); //throws error, not case sensitive
}

我希望如下使用:

//Get the types
var genTyp = GetTypeOf(genPath,genName);
var itemTyp = GetTypeOf(itemPath,itemName);

//Put them together:
var typ = getType.MakeGenericType(itemTyp);

这会落在第一行,System.TypeLoadException说明:

Could not load type <TypeName here> from assembly <AssemblyName here>

我尝试了许多创建通用的排列,包括提供完整的类名MyNamespace.Generic<System.String>。当我指定从包含泛型类型的同一程序集加载非泛型类型时,它可以正常工作。

2 个答案:

答案 0 :(得分:4)

不幸的是,使用带有泛型类型的GetType并不可读。您必须使用完全限定类型名称,即使对于通用参数:例如,TestType<object>的内容如下:

TestType`1[[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

您的示例代码不包含类型声明,因此您必须使用它。您可以尝试使用此代码段并查看调试器所说的内容:

string typeName = typeof(MyNamespace.Generic<>).Name;
string fullTypeName = typeof(MyNamespace.Generic<>).FullName;

结果应该可以帮助您获得正确的类型名称。

答案 1 :(得分:3)

根据Carsten上面的回答,我调整了我的GetTypeOf方法如下:

    public Type GetGenericTypeOf(string assemblyPath, string genericClass, string itemQualifiedClass)
    {
        string typString = String.Format("{0}`1[[{1}]]",genericClass,itemQualifiedClass)
        var asmbly = System.Reflection.Assembly.LoadFrom(assemblyPath); //open assembly
        return asmbly.GetType(typString, true, true); //throws error, not case sensitive
    }

然后我可以按如下方式使用它:

var itemTyp = GetTypeOf(itemPath,itemName);
var genTyp = GetGenericTypeOf(genPath,genName,itemTyp.AssemblyQualifiedName);

//This genTyp is then good to go:
var genInst = Activator.CreateInstance(getTyp);

不需要MakeGenericType因为返回的genType会绕过此步骤。

我现在已经完整写了这篇文章,包括我博客here上的VB.Net版本的代码。