如何存储和使用从公共基类型派生的不同类型的数组?

时间:2011-06-17 20:34:24

标签: c# types polymorphism base

标题可能需要一些解释,所以这就是我想要做的事情:

  • UI元素的通用基本类型,例如BasePanel
  • 可以定义更多来自BasePanel的专用元素。例如,按钮和文本框。
  • 将存储元素列表(类型为BasePanel,以便存储专用元素)
  • 此列表将循环显示每个帧并绘制(暂时忽略优化)

使用示例:

class UIButton : BasePanel
{
    public override void Draw(blah)
    {
        // Specialised drawing code
    }
}

foreach (BasePanel Element in StoredElements)
{
    Element.Draw(blah);
}

这个问题是它不会运行专门的代码;它只会运行BasePanel代码。 如何改进它以便它将运行专用代码?我可以在BasePanel上存储元素的类型,然后在运行时转换为它吗?

我已经尝试将BasePanel存储在存储原始类型的Container类中,但我无法访问该方法 - 例如:

foreach(ElementContainer Container in StoredElements)
{
    Type t = Container.OriginalType;
    object el = Container.Element;

    Convert.ChangeType(el, t); //Can't use the returned object!

    t Element = (t)Convert.ChangeType(el, t); //This would be perfect, but it doesn't work.
}

感谢您的帮助。这让我的大脑爆炸了。

4 个答案:

答案 0 :(得分:2)

使用以下代码对我100%有效:

class BasePanel
{
    public virtual void Draw(string blah)
    {
        Console.WriteLine("Base: " + blah);
    }
}

class UIButton : BasePanel
{
    public override void Draw(string blah)
    {
        Console.WriteLine("UIButton: " + blah);
    }
}

class Program
{
    static void Main(string[] args)
    {
        List<BasePanel> list = new List<BasePanel>();

        list.Add(new BasePanel());
        list.Add(new UIButton());
        list.Add(new BasePanel());
        list.Add(new UIButton());
        list.Add(new UIButton());

        foreach (var b in list)
        {
            b.Draw("just a string");
        }
    }
}

你的错误来自你的绘图代码/逻辑。

答案 1 :(得分:0)

看起来您的示例应该可以正常工作,但您可以尝试将Draw方法(以及您需要的任何其他多态性)提取到Inerface中,然后在列表中的每个类中实现接口。

答案 2 :(得分:0)

正如DarkSquirrel所说,你可以将父类的功能声明为虚拟。这应该允许您的代码运行专门的代码

答案 3 :(得分:0)

您尝试执行哪种特殊类型

如果你有

class Bar {
  public virtual void Draw() {
    DO STUFF!
  } 
}

class Foo : Bar {
  override public virtual Draw() {
    DO MORE STUFF!
  }
}

然后在你的代码中的某个地方

Bar[] data = new Bar[] { new Foo(), new Bar()};
foreach (Bar elem in data) {
  elem.Draw();
}

第一个元素将在Foo中为第一个elem执行重写代码,在Bar中为第二个元素执行代码。即使你向下投射一个项目,在方法中执行的代码仍然是原始对象中的代码(elem.GetType()将返回Foo类型的Foo。