【问题标题】:Inherited class casting继承类铸造
【发布时间】:2013-01-25 16:23:15
【问题描述】:

我有这个基类:

namespace DynamicGunsGallery
{
    public class Module
    {
        protected string name;

        public virtual string GetName() { return name; }
        public virtual string GetInfo() { return null;  }
    }
}

我正在创建从基类继承的动态库,例如(AK47.dll)

namespace DynamicGunsGallery
{
    public class AK47 : Module
    {
        public AK47() { name = "AK47";  }

        public override string GetInfo()
        { 
            return @"The AK-47 is a selective-fire, gas-operated 7.62×39mm assault rifle, first developed in the USSR by Mikhail Kalashnikov.
                    It is officially known as Avtomat Kalashnikova . It is also known as a Kalashnikov, an AK, or in Russian slang, Kalash.";
        }
    }
}

我正在使用这个 (inspired by this link) 加载动态库:

namespace DynamicGunsGallery
{
    public static class ModulesManager
    {
        public static Module getInstance(String fileName)
        {
            /* Load in the assembly. */
            Assembly moduleAssembly = Assembly.LoadFile(fileName);

            /* Get the types of classes that are in this assembly. */
            Type[] types = moduleAssembly.GetTypes();

            /* Loop through the types in the assembly until we find
             * a class that implements a Module.
             */
            foreach (Type type in types)
            {
                if (type.BaseType.FullName == "DynamicGunsGallery.Module")
                {
                    //
                    // Exception throwing on next line !
                    //
                    return (Module)Activator.CreateInstance(type);
                }
            }

            return null;
        }
    }
}

我在这两个中都包含了基类,我的可执行文件包含 ModuleManager 和 dll 库。我编译的时候没有问题,但是当我运行这段代码时,我得到了一个错误:

InvalidCastException 未处理。

无法将 DynamicGunsGallery.AK47 类型的对象转换为类型 DynamicGunsGallery.Module

所以问题是:为什么我不能将派生类转换为基类?

还有其他方法可以加载动态库并使用基类中的方法“控制”它吗?

【问题讨论】:

  • 您是否有可能将Module 类声明了两次,即在主程序和AK47.dll 中?您应该将类​​型名称字符串比较替换为 typeof(Module).IsAssignableFrom(type) 调用。
  • 是的,我已经在主程序和库中声明了Module。我在主程序中有它,因为我想使用它的方法来控制库,所以我猜主程序(编译器)必须知道它的声明。我在库中拥有它,因为每个库都会派生自它,所以我再次猜测,编译器必须知道它的声明才能编译衍生。我错了吗? ...我使用字符串比较,因为typeof() 对我不起作用。
  • 另外,尝试拆分最后一行:object something =activator.createinstance,然后是return (module)something。设置断点并确保某些内容是您期望的类型?
  • 是的,你错了。在您的子库中,您不能重新声明模块;您必须从原始库中引用该模块。从包含 ak 类的项目中添加对主项目的引用。我还会考虑更改命名空间,以明确您有两个库正在运行
  • 仅仅因为两个类(在不同的程序集中定义)具有相同的名称,它们不会以某种方式神奇地结合并成为同一个类。我不清楚为什么要动态执行此操作。 AK47.dll不能通过引用主程序的DLL来编译吗?

标签: c# casting


【解决方案1】:

从你的 cmets 出发:

在你的子库中,你不能重新声明模块;您必须从原始库中引用该模块。

从包含 ak 类的项目中添加对主项目的引用。

我还考虑更改命名空间,以明确您有两个库在运行

【讨论】:

  • 谢谢 :) ...即使typeof().IsAssignableFrom() 现在也可以使用...是的,我也会更改命名空间 :)
猜你喜欢
  • 2011-08-01
  • 1970-01-01
  • 2021-06-14
  • 2020-01-18
  • 1970-01-01
  • 2018-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多