-->

.NET:无法施展对象的接口它实现(.NET: Unable to cast object to i

2019-08-22 05:43发布

我有一个类(TabControlH60),这两个从基类(用户控件)继承并实现的接口(IFrameworkClient)。 我实例使用.NET Activator类的对象。 随着返回的情况下,我可以同时投射到用户控件的基类,而不是接口。 我得到的例外是下面的一小段代码片段。 如何转换为界面?

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'."}

Answer 1:

我的帽子和我的提供“插件” -Functionality库同样的问题......我终于工作...

这里是我的问题:我有一个主用汇编插件,一个组件,插件(Plugin.dll)AND(重要的)另一个组件提供插件的功能(Library.dll)。

所述Plugin.dll引用的主组件(为了能够延长它),并与插件-FUNC的Library.dll。 - 这是二进制到了一个目录“./Plugins”相对于主要部件。

主要组件还引用的插件,FUNC。 装配,以使用“插件管理”中写道。 这种“插件管理”得到的路径,并通过反射加载所有* .dll文件,以分析是否有“IPlugin” - 接口(其中来自Library.dll太)。

每次我叫插件管理加载它无法施展他们“IPlugin”虽然他们实现它的插件。

我几乎气疯了 - 但后来我发现了问题的全部。 通过编写插件,不仅传出了“Plugin.dll”,但“Library.dll”写入“./Plugins”目录。 意外地加载“Library.dll”我的插件管理,每次我现在有两种类型的“IPlugin”的 - 一个在从主组件和通过插件管理我装一个实际使用的“Library.dll” - 和那些是不兼容的!

注意 - 如果你只是不加载“./Plugins/Library.dll”你仍然遇到问题 - 因为如果你加载‘Plugin.dll’它引用‘Library.dll’,那么它只是使用了在同一个目录下。 .. TILT ...! 我的插件管理现在只是删除“Library.dll”的地方找到它。

线索是:一定不要在不同环境下访问两个组件!



Answer 2:

这里最可能的原因是IFrameworkClient是从不同的组件,在两种情况下,因此是一个不同的.NET类型。 即使是相同的代码,也可以是不同的类型。

检查AssemblyQualifiedName 。 还要注意,如果要加载这个组件,反射,你可以得到不同类型甚至相同AssemblyQualifiedName,由于负载环境。



Answer 3:

定义IFrameworkClient接口独立命名空间(必须具有命名空间)独立的项目(类库)。然后添加类库的refrence来控制项目,主体工程



Answer 4:

东西告诉我你的示例代码,留下一些东西...

class Program
{
    static void Main(string[] args)
    {
        var type = typeof(MyClass);
        object obj = Activator.CreateInstance(type);
        Type[] interfaces = obj.GetType().GetInterfaces();

        var m_Client = (UserControl)obj;          
        IFrameworkClient fc = (IFrameworkClient)obj;
    }
}

public interface IFrameworkClient { }

public class UserControl { }

public class MyClass : UserControl, IFrameworkClient { }

这编译和运行。

我打赌你尝试施放前含IFrameworkClient定义的DLL还未被加载。 这可以当你使用Activator.CreateInstance发生。

尝试插入var forceLoad = typeof(IFrameworkClient); 之前剧组。



Answer 5:

Interface 处于不同的组装和我得到我的课动态run-time在不同的组件, interface casting将会失败像你的样品(C#知道我们的界面为不同类型的比一个从继承类)。

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

当我敢肯定,我的Class已经从提及继承Interface (EQ。 IFrameworkClient ),所以我写一个魔法行这样的代码

dynamic fc = obj as IFrameworkClient ?? (dynamic) obj;

通过这种技术,您可以:

  • 这行代码后编写的代码fcdesign time对基Interface members信息和VS编辑智能系统。
  • 防止任何接口铸造错误run-time

笔记:

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


Answer 6:

如果类FPG.H60​​.AFF.TabControlH60实际上并实现IFrameworkClient应该没有理由,这将失败。 我能想到的唯一的事情导致此例外是如果包含IFrameworkClient大会强烈命名和标签控件对象恰好引用一个不同的版本包含组装,或者您所使用的名称IFrameworkClient不同的接口。



Answer 7:

在我来说,我不得不添加一个生成事件复制所需的DLL,因为我是创建实例并分配在运行时的接口类型。 否则,DLL加载可能不是最先进最新的DLL,因此可能无法投射到该接口。

我之所以使用在这种情况下生成事件(而不是添加该DLL作为参考)是该体系结构是这样的:主应用程序应该只引用接口类型,和其他一切应当动态加载。

TLDR; 在从另一个DLL动态加载类型的情况下,确保您复制最近该DLL使用生成事件的bin目录的版本,否则铸造时看来,它应该可能无法正常工作。



Answer 8:

演员是行不通的,因为你试图从类型转换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

一个多一块拼图。 接口不派生自object : http://blogs.msdn.com/ericlippert/archive/2009/08/06/not-everything-derives-from-object.aspx



文章来源: .NET: Unable to cast object to interface it implements