.NET:无法将对象转换为它实现的接口

use*_*327 24 c# casting interface base-class activator

我有一个类(TabControlH60),它继承自基类(UserControl)并实现一个接口(IFrameworkClient).我使用.NET Activator类实例化对象.使用返回的实例,我可以转换为UserControl基类,但不能转换为接口.我得到的例外是在代码snipet下面.如何转换为界面?

object obj = Activator.CreateInstance(objType);
Type[] interfaces = obj.GetType().GetInterfaces(); // contains IFrameworkClient

m_Client = (UserControl)obj;                 // base class cast works
IFrameworkClient fc = (IFrameworkClient)obj; // interface cast fails

// Note: The (IFrameworkClient)obj cast works fine in the debugger Watch window.
{"Unable to cast object of type 'FPG.H60.AFF.TabControlH60' to type 
    'FPG.AFF.Interfaces.IFrameworkClient'."}
Run Code Online (Sandbox Code Playgroud)

小智 41

我遇到了同样的问题,我的库提供了"插件"功能......我终于得到了它......

这是我的问题:我有一个主要程序集使用插件,一个程序集与插件(Plugin.dll)和(重要)另一个程序集提供插件功能(Library.dll).

Plugin.dll引用了主程序集(为了能够扩展它)和带有plugin-func的Library.dll. - 它的二进制文件到达相对于主程序集的目录"./Plugins".

主程序集还引用了plugin-func.汇编为了使用"PluginManager"而写的.这个"PluginManager"获取一个路径并通过反射加载所有*.dll文件,以分析是否存在"IPlugin"接口(也来自Library.dll).

我每次调用PluginManager加载插件时都无法将它们转换为"IPlugin",尽管它们实现了它.

我几乎生气了 - 但后来我发现了整个问题.通过编译插件,不仅有"Plugin.dll"而且"Library.dll"写入"./Plugins"目录.每次使用我的PluginManager意外加载"Library.dll"时,我现在有两种类型的"IPlugin" - 一个在主程序集中使用的实际"Library.dll"中,另一个是通过我的PluginManager加载的 - 那些是不相容的!

注意 - 如果你只是不加载"./Plugins/Library.dll",你仍然遇到问题 - 因为如果你加载"Plugin.dll"引用"Library.dll",那么它只是使用同一目录中的那个. ..倾斜...... !! 我的PluginManager现在只删除它找到它的"Library.dll".

线索是:确保您不会在不同的上下文中访问两个程序集!

  • 你,先生,刚刚解决了我的问题,现在困扰我4个小时,干脆离开了.非常感谢! (4认同)

Mar*_*ell 11

这里最可能的原因是IFrameworkClient在两种情况下来自不同的程序集,因此是不同的.NET类型.即使它是相同的代码,它也可以是不同的类型.

检查一下AssemblyQualifiedName.另请注意,如果使用反射加载此程序集,即使使用相同的AssemblyQualifiedName,也可以获得不同的类型,这要归功于load-context.


RAM*_*RAM 5

Interface在不同的程序集中并且我在不同的程序集中动态获取我的类时run-timeinterface casting将像您的示例一样失败(C# 知道我们的接口是一种不同于类继承的类型)。

在这种情况下,这是我简单而有用的技术:

当我确定我Class已经从提到的Interface(eq. IFrameworkClient)继承了,所以我写了这样一行神奇的代码

dynamic fc = obj as IFrameworkClient ?? (dynamic) obj;
Run Code Online (Sandbox Code Playgroud)

通过这种技术,您可以:

  • fcdesign time基于Interface members信息和 vs 编辑器智能系统的这行代码之后编写您的代码。
  • 防止任何接口转换错误 run-time

笔记:

  • 您需要C# v4使用dynamic类型
  • 通常我不喜欢dynamic在我的代码中使用类型,但它可以在某些情况下帮助我们


Ken*_*nky -2

转换不起作用,因为您正在尝试从类型转换object为接口。如果将接口投射线替换为:

IFrameworkClient fc = (IFrameworkClient)m_Client;

它会起作用的。

或者,我稍微确定您可以使用操作符将对象从对象转换为界面as

有关详细信息,请参阅本文: http://blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference- Between-as-and-cast-operators.aspx

拼图又多了一块。接口并非源自objecthttp://blogs.msdn.com/ericlippert/archive/2009/08/06/not-everything-derives-from-object.aspx