C#多态 - 如何不对硬编码类型

时间:2009-01-17 21:44:32

标签: c# oop

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

我想拥有一个可以创建命令的GUI,这可能需要某种列表框来选择要创建的命令类型。问题是,如何在没有硬编码的情况下使用该列表框并使其显式引用我所创建的所有类的显式引用。

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

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

更新:我刚发布了一个跟进问题here

4 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

使用策略模式(link to wikipedia),您将通过调用或反射执行该方法。 由于有很多例子,我不会在这里列出。

答案 2 :(得分:1)

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

 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类通常是很好的。

答案 3 :(得分:0)

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