如何在C#中创建通用列表/模板列表

3

我有一个主类,它有几个继承成员,所有这些成员都重载了父类的相同绘制方法,但具有不同的初始化方法。是否可能对每个继承类使用相同的列表类型,从而能够遍历绘制方法?我相信你可以在C++中使用模板来实现这一点,但似乎找不到在C#中实现的方法。以下是一个示例:

class MainMenu : ExpandingWindow{
   Init(A,B)
   Draw(D)
}

class SideMenu : ExpandingWindow{
   Init(A,B,C)
   Draw(D)
}

我希望能够做到以下几点:

 WindowList List<ExpandingWindow>

 WindowList.Add(new MainMenu)
 WindowList.Add(new SideMenu)

 WindowList[0].Initialize(A,B)
 WindowLIst[1].Initialize(A,B,C)

And:

 for each window in WindowList{
   window.Draw(D)
 }

我很确定我在这里漏掉了什么。我不一定要以这种方式做,我更想找到处理这些情况的通用方法。

谢谢!

3个回答

2

尝试:

IList<ExpandingWindow> windows = new List<ExpandingWindow>();

// initialize them via constructor
windows.Add(new MainMenu(A, B));    
windows.Add(new SideMenu(A, B, C));

foreach(var window in windows) {
    window.Draw();
}

1
如果每个子类都有不同的方法,则它们不属于接口,不能在没有显式转换的情况下调用(这在面向对象编程中是不好的)。
您可能想要做的是将参数传递给它们的构造函数,然后使用相同签名调用接口方法:
class ExpandingWindow
{
     public virtual void Draw(D obj) { ... }
}

public class MainMenu : ExpandingWindow
{
     public MainMenu(A a, B b)
     { 
         // assign MainMenu-specific parameters
     }

     // inherit Draw from the base class,
     // or override it if necessary
}

public class SideMenu : ExpandingWindow
{
     public SideMenu(A a, B b, C c)
     { 
         // assign SideMenu-specific parameters
     }

     // inherit Draw from the base class,
     // or override it if necessary
     public override Draw(D d)
     {
         // some side-menu specific stuff
         d.DoStuff();

         // call the base method after that
         base.Draw(d);
     }
}

当您创建具体实例时,您将传递特定的参数(因为此时您必须知道要实例化哪个类):

List<ExpandingWindow> windows = new List<ExpandingWindow>();

windows.Add(new MainMenu(a, b));
windows.Add(new SideMenu(a, b, c));

foreach (var w in windows)
   w.Draw(d);

我很高兴你提出这个问题,因为我也有同样的想法! :) 我已经尝试了一下,但是我又遇到了另一个问题。构造函数是: MainMenu(A,B,C) 但是写成 list.Add(new MainMenu(A,B,C)) 并没有起作用。编译器告诉我没有带3个参数的方法,但我相信它是存在的...所以我肯定错过了什么! - Tormod Haugene
从您的评论中,我再次尝试了一下。看起来我在构造函数中包含了一个void语句。我去掉了void,现在它可以工作了。非常好的反馈。谢谢! - Tormod Haugene

0
你需要在基类 ExpandingWindow 中创建一个抽象虚拟方法,然后在派生类中重写该方法。
另一种选择是定义一个 IExpandingWindow 接口,其中包含一个 Draw 方法,并在你的类中实现它。

听起来像Tormod已经完成了那个,但是在创建通用列表方面遇到了问题。 - Zbigniew
我已经将Init方法实现为抽象方法,Draw方法实现为虚方法。但是我可能做得不好;因为现在我必须为ExpandingWindow中每个继承类中的不同Init方法重载Init方法(由于不同的方法参数)。有没有什么解决方法?将ExpandingWindows实现为接口是否有帮助? - Tormod Haugene

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接