.NET反射判断接口可赋值:调试即时窗口为true运行时为false?
TL;DR
我有两个独立的接口副本,可查看重复问题的对应回答,或本问题底部的更新了解原因详情。
问题概述
我正在通过反射从程序集加载类型:
foreach (string assemblyPath in assemblyPaths) { Assembly assembly = Assembly.LoadFrom(assemblyPath); if (assembly.GetTypes().Any(a => typeof(IChannel).IsAssignableFrom(a))) { DoSomethingCool(); } }
调试代码时我在逻辑判断行打了断点,在即时窗口中执行该判断结果为true:
但继续执行代码时,if语句对应的代码块始终不会执行,说明该行代码运行时判断结果为false,我找不到问题原因。
- 我已尝试重启Visual Studio和电脑,排除软件故障可能。
- 我试过将判断逻辑反向写为
a.IsAssignableFrom(typeof(IChannel))1。 - 我也检查过
.GetTypes()的返回结果,要找的目标类型确实存在。 - 我单独对目标类型
.GetTypes()[0]做了相同检查,结果符合预期为true。
1:该写法在即时窗口中判断结果为false,也不会进入if块,符合我的预期。
疑问
还有哪些原因会导致调试时出现这种判断结果不一致的问题?
问题原因
我的问题根源是:IChannel定义在一个类库中,执行程序集引用了该类库,被加载的程序集也引用了该类库,但被加载的程序集有一份自己本地的IChannel定义类库副本。
我最终通过相关技术提问找到了答案,其中一条回答对我帮助最大,摘录如下:
我当时都快疯了,最后找到了问题所在:编译插件时,不仅会生成"Plugin.dll",还会把"Library.dll"输出到"./Plugins"目录。我的插件管理器每次加载插件时意外把这个"Library.dll"也加载了,导致存在两个"IPlugin"类型:一个是主程序集引用的正式"Library.dll"中的类型,另一个是插件管理器加载的副本中的类型,二者互不兼容!
我保留这个问题是因为如果网上有对应我问题标题的结果,我就能更快找到答案。我当时走了不少弯路,通过额外步骤才找到解决问题的相关线索:
- 我把
.Any的判断条件改成了检查.GetInterface("IChannel") != null。 - 我用
Activator创建了目标类型的实例。 - 我尝试把实例强制转换为
IChannel类型。
测试代码示例如下:
var type = assembly.GetTypes().First(f => f.GetInterface("IChannel") != null); var instance = (IChannel)Activator.CreateInstance(type);
上述代码片段可能存在语法问题,复制使用前请自行验证。我早已删除了这段测试代码。
内容的提问来源于stack exchange,提问作者Taco
相关产品推荐
相关产品推荐

