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

本文关键字:类型 基类 派生 同类型 数组 何存储 存储 | 更新日期: 2023-09-27 17:59:21

标题可能需要一些解释,所以我要做的是:

  • 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.
}

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

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

它使用以下代码对我来说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");
        }
    }
}

你的错误源于你的绘图代码/逻辑。

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

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

您尝试执行的专用类型是什么

如果你有

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();
}

第一个elem将执行Foo中的overriden代码用于第一个elem,执行Bar中的代码用于第二个elem。即使向下转换一个项,在方法中执行的代码仍然是原始对象中的代码(并且elem.GetType()将为Foo类型返回Foo。