如何按类型名称获取通用接口的类型?

时间:2012-06-13 00:08:33

标签: .net generics reflection

好的,这是我的问题:

我有一个xml文件,其中包含方法及其参数的记录。此xml文件记录了ID值列表,其中.net泛型接口类型名称如下:

System.Collections.Generic.IList`1[CoreLib.Domain.MyClass]

我知道大多数这些参数都是通用列表或字典。当我尝试在我从xml读取的字符串值上使用GetType时,它都返回null,如果我尝试将throw异常标志设置为true,则会抛出以下消息:

  

“无法从中加载类型'CoreLib.Domain.MyClass'   assembly'TestLibrary,Version = 1.0.0.0,Culture = neutral,   公钥=空”。“

获得可以拉回我可以填充的实际类型的最佳策略是什么?提前谢谢!

UPDATE 我试图将汇编引用添加到字符串名称,如下所示:

Type.GetType("System.Collections.Generic.List`1[CoreLib.Domain.MyClass,CoreLibrary]")

coreLibAssembly.GetType("System.Collections.Generic.List`1[CoreLib.Domain.MyClass,CoreLibrary]")

两者都会产生一个null对象,或者如果我请求抛出异常,那么如果我没有指定程序集名称,则会得到相同的消息。我还尝试使用程序集绑定日志查看器,但列表中没有应用程序,并且在运行我的代码之后,应用程序中似乎没有任何内容出现(它位于由nunit执行的测试项目中)。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您通常可以将字符串传递给Type.GetType()。例如:

Type t = Type.GetType("System.Collections.Generic.Dictionary`2[System.String,System.Int32]");

我怀疑在你的情况下,CLR不知道如何解决类型CoreLib.Domain.MyClass。您可能需要通过指定程序集来帮助它,如本示例taken from MSDN

Type.GetType("System.Collections.Generic.Dictionary`2[System.String,[MyType,MyAssembly]]")

如果在指定程序集之后仍然“炸毁”(下次,建议您更好地定义,例如使用特定错误,异常或堆栈跟踪: - )尝试运行{{3} 以管理员身份(否则它会无声地失败)来记录绑定失败。

答案 1 :(得分:0)

我已经弄清楚了。问题是如何引用程序集,以及GetType方法如何计算程序集的位置。我最终用GetType的Assembly Resolver匿名代表解决了这个问题:

    result = Type.GetType(typeName + ",mscorlib", //<-- needing to identify the mscorlib  for generics!
        //this anonymous delegate method is used by the GetType Framework to identify and return the correct assembly for the given assembly name.
        //most of this is default, except to handle the mscorlib library
        delegate(AssemblyName potentialAssembly)
        {
            if (potentialAssembly.Name == coreLibAssembly.FullName)
                return coreLibAssembly; // this was never called, I had to check the namespace within the rest of my code
            else if (potentialAssembly != null)
                return Assembly.Load(potentialAssembly);
            else
                return null;
        },
        //this anonymous delegate is used to return the type specific to the assembly. this method is called for each nested generic, 
        //so we don't have to parse the type string name by hand.
        delegate(Assembly potentialAssembly, string inputTypeName, bool ignoreCase)
        {
            if (inputTypeName.StartsWith("CoreLib.Domain"))
                return coreLibAssembly.GetType(inputTypeName, true, ignoreCase);
            else if (potentialAssembly != null)
                return potentialAssembly.GetType(inputTypeName, true, ignoreCase);
            else
                return Type.GetType(inputTypeName, true, ignoreCase);
        }, true);

现在,如果泛型Type.GetType(字符串typeName)不起作用,我使用此代码解析类型字符串,并将程序集与给定typeName字符串变量中的相应类型名称匹配。