【问题标题】:C# says that A is not an instance of B yet A implements interface BC# 说 A 不是 B 的实例,但 A 实现了接口 B
【发布时间】:2012-12-11 13:41:37
【问题描述】:

问题 - 我正在尝试插件开发,除了尝试将对象 A 转换为对象 B 之外,尽管 A 实现了 B,但一切进展顺利。

界面:

namespace DynamicApplications
{
    public interface IPlugIn
    {
        string Name { get; set; }
        IPlugInHost myHost { set; }
        void Show();
    }

    public interface IPlugInHost
    {
        bool Register(IPlugIn plug);
    }
}

实现IPlugIn的类

namespace plugInOne
{
    class PlugIn : IPlugIn
    {
        IPlugInHost _myHost;

        public string Name
        {
            get
            {
                return "Plug-In One";
            }
            set
            {
            }
        }

        public IPlugInHost myHost
        {
            set
            {
                _myHost = value;
            }
        }

        public void Show()
        {
        }
    }
}

现在是实例化的代码:

        String path = Application.StartupPath;
        string[] assemblyNames = Directory.GetFiles(path, "*.dll");
        plugs = new IPlugIn[assemblyNames.Length];

        for(int i = 0; i < assemblyNames.Length; i++)
        {
            string Name = assemblyNames[i];
            Name = Name.Substring(Name.LastIndexOf("\\") + 1, Name.Length - Name.LastIndexOf("\\") - 1);
            Name = Name.Remove(Name.LastIndexOf(".dll"));
            assemblyNames[i] = Name;
        }

        for (int i = 0; i < assemblyNames.Length; i++)
        {
            Assembly DLL = Assembly.Load(assemblyNames[i]);

            if(DLL != null)
            {
                try
                {
                    Object p = Activator.CreateInstance(DLL.GetType(assemblyNames[i] + ".PlugIn"));

                    if (p is DynamicApplications.IPlugIn)
                    {
                        MessageBox.Show("YES!!!!");
                    }
                    else
                    {
                        MessageBox.Show("no>?>?>>><<?????");
                    }

                    plugs[i] = (IPlugIn)p;
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

请注意,调试器显示p 实际上已实例化并可访问

应用程序总是点击MessageBox.Show("no&gt;?&gt;?&gt;&gt;&gt;&lt;&lt;?????");

请帮忙

艾登

编辑

P 的类型:

还有

YET pluginOne.PlugIn 实现了 IPlugIn

【问题讨论】:

  • 让您的消息框显示p 的类型。一旦你知道了,你可能就不需要更多的帮助了。
  • 您似乎引用了不同的程序集。常见错误。
  • 我(1)将接口和实例化代码放在控制台应用程序中,(2)从类库中引用控制台应用程序并将实现放入库中,(3)构建库并将控制台应用程序文件夹中的 DLL,(4) 运行控制台应用程序和 MessageBox.Show("YES!!!!"); 的控制台等效项 did 触发。在原则中,你什么都不做;在practice中,可能您的 DLL 不存在,或者已经过时,或者其他什么。

标签: c# plugins dll interface polymorphism


【解决方案1】:

您引用的DynamicApplications.IPlugIn 与将包含在程序集中的接口不同。

您需要从程序集中获取 IPlugin 实例,而不是使用本地实例。如果您执行以下操作,则您的检查代码很好:

public interface IA { }
public class A :IA { }


object a = Activator.CreateInstance<A>();
if (a is IA)
    Console.WriteLine("Yes");

但是,您从其他地方获取您的A(在上述上下文中),并且仍在尝试引用您的本地版本的IA - 因此您需要从您的程序集中获取您的接口而不是尝试引用它本地。也许你可以这样做:

if (objA.GetType().GetInterfaces().Any(x => x.Name == "IA"))
  Console.WriteLine("Yes");

【讨论】:

  • 好吧,快点——我很困惑。我实例化了一个类型为plugInOne.PlugIn 的对象,它实现了DynamicApplications.IPlugIn,然后测试实例化的对象是否为DynamicApplications.IPlugIn 类型(它应该是因为我编码它的方式)。抱歉,请多解释一下
  • o 和 ps。 if (objA.GetType().GetInterfaces().Any(x =&gt; x.Name == "IA")) Console.WriteLine("Yes");通过
  • 您正在从程序集中实例化 type,然后检查您实例化的类型是否实现了接口的 LOCAL 版本,程序集中的 type 将实现接口的程序集版本而不是本地版本,因为它对此一无所知。
  • @LukeHennerley 是什么让您认为有本地版本的界面? (编辑:也许那条评论说名称检查通过了,我猜......)
  • @AidenStrydom 没问题,通常最简单的问题是最能解决问题的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-22
  • 1970-01-01
  • 1970-01-01
  • 2014-11-02
  • 2019-07-26
  • 2011-08-01
  • 2014-03-29
相关资源
最近更新 更多