3

好的,这是我的问题:

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

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

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

“无法从程序集 'TestLibrary,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null' 加载类型 'CoreLib.Domain.MyClass'。”

获得可以拉回我可以填充的实际类型的东西的最佳策略是什么?先感谢您!

更新我试图将程序集引用添加到字符串名称,如下所示:

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

或者

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

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

有什么想法吗?

4

2 回答 2

1

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

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

我怀疑在您的情况下,CLR 不知道如何解析 type CoreLib.Domain.MyClass。您可能需要通过指定程序集来帮助它,例如取自 MSDN的示例:

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

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

于 2012-06-13T00:44:09.493 回答
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(string typeName) 不起作用,我使用此代码解析类型字符串,并将程序集与给定 typeName 字符串变量中的相应类型名称匹配。

于 2012-06-13T19:42:58.687 回答