【问题标题】:Loading a generic type using Assembly.LoadFrom使用 Assembly.LoadFrom 加载泛型类型
【发布时间】:2012-08-20 10:43:39
【问题描述】:

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

我需要根据泛型类型的名称以及作为泛型类型参数的类型名称加载一个泛型类型。所以从乔恩的例子中我会有:

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&lt;System.String&gt;。当我指定一个非泛型类型从包含泛型类型的同一个程序集中加载时,它可以正常工作。

【问题讨论】:

  • genType-assembly所依赖的所有程序集都可以加载吗?
  • 是的。我可以毫无问题地从 genType 的程序集中加载非泛型类。

标签: c# generics late-binding


【解决方案1】:

不幸的是,将 GetType 与泛型类型一起使用并不那么可读。您必须使用完整的限定类型名称,即使是泛型参数:。例如,TestType&lt;object&gt; 如下所示:

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

您的示例代码不包含类型声明,因此您必须尝试一下。你可以试试这段代码 sn-p 看看调试器是怎么说的:

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

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

【讨论】:

  • 非常感谢 - 这让我走上了正确的道路。请参阅我的最终修复答案。
【解决方案2】:

根据上面 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 版本的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 2023-02-23
    • 2021-04-23
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    相关资源
    最近更新 更多