【问题标题】:C# polymorphism - how not to hardcode typesC# 多态性 - 如何不对类型进行硬编码
【发布时间】:2009-01-17 21:44:32
【问题描述】:

我正在制作一个简单的面向对象的测试程序来尝试帮助我掌握 OOP。我有一个具有方法 Run(params object[] parameters) 的 ICommand 接口,并且我有各种使用该接口并实现自己的运行版本的类。每个类还有一个 name 属性,它说明命令是什么以及它的作用。

我想要一个可以创建命令的 GUI,这可能需要某种列表框来选择要创建的命令类型。问题是,我如何制作该列表框并使其工作而无需在 switch 语句中进行硬编码,并显式引用我创建的所有类。

我确定这是一个非常简单的问题,我应该知道答案,但我就是想不出来!不过我肯定有答案。

哦,我希望一些回复会说阅读设计模式书:图书馆中唯一的副本目前已出版,但我会尽快阅读!

更新:我刚刚发布了一个后续问题here

【问题讨论】:

    标签: c# oop


    【解决方案1】:

    将所有类存储在 ICommand 的通用列表中,使用命令名称覆盖 ToString() 并将列表的内容应用到列表框。

    var commandlist = new List<ICommand>();
    commandList.add(new Command("Run"));
    commandList.add(new Command("Walk"));
    commandList.add(new Command("Crawl"));
    

    【讨论】:

    • 感谢您的回复。可惜我不太明白你的意思。什么是 ICommand 的通用列表?
    • 添加了一些代码。 Command 是一个实现 ICommand 的类。
    • 我刚刚在这里发布了一个后续问题:stackoverflow.com/questions/454163/…
    【解决方案2】:

    使用策略模式 (link to wikipedia),您将通过调用或反射执行该方法。 例子很多,这里就不一一列举了。

    【讨论】:

      【解决方案3】:

      我不确定您是否真的需要避免显式调用构造函数。但是,您可以通过反射来实现 - 如果您的类型的构造函数不需要任何参数:

       var commands = new List<object>();
       foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
       {
          foreach (Type type in assembly.GetTypes())
          {
             if (type.GetInterface(typeof(ICommand).FullName) != null)
             {
                commands.Add(Activator.CreateInstance(type));
             }
          }
       }
      

      此代码假定定义 ICommand 实现的程序集已加载,并且不执行任何所需的错误处理。

      另一种方法是读取配置文件,其中包含要实例化的类型名称(甚至可能是要加载的程序集)。

      但是,在大多数情况下,不需要这样做。拥有一个只调用一堆构造函数的 CommandFactory 类通常是很好的。

      【讨论】:

        【解决方案4】:

        您可以使用反射找到所有实现您感兴趣的接口的类;然后用它来填充你的列表

        【讨论】:

          猜你喜欢
          • 2021-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-28
          • 2021-12-22
          • 1970-01-01
          • 2012-03-12
          • 1970-01-01
          • 2020-01-08
          相关资源
          最近更新 更多