Как я могу хранить и использовать массив разных типов, полученных из общего базового типа? - PullRequest
1 голос
/ 18 июня 2011

Заголовок может нуждаться в небольшом объяснении, поэтому вот что я пытаюсь сделать:

  • Общий базовый тип для элементов пользовательского интерфейса, например 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 ]

2 голосов
/ 18 июня 2011

Это работает на 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");
        }
    }
}

Что не так с вашим, происходит из вашего кода / логики рисования.

0 голосов
/ 18 июня 2011

Какой специализированный тип вы пытаетесь выполнить

если у вас есть

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 для первого элемента и код в Bar для второго. Даже если вы приведете элемент вниз, код, выполняемый в методах, все равно будет кодом исходного объекта (и elem.GetType() вернет Foo для типа Foo.

0 голосов
/ 18 июня 2011

Как заявил DarkSquirrel, вы можете объявить функции родительского класса как виртуальные. Это должно позволить вашему коду запускать специализированный код

0 голосов
/ 18 июня 2011

похоже, ваш пример должен работать, но вы можете попробовать извлечь метод Draw (и любые другие, которые вам нужны для полиморфизма) в Inerface, а затем реализовать интерфейс в каждом из классов, которые вы хотите в списке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...