Расширение класса новым вложенным классом

первый вопрос поэтому я открыт для консультаций по эффективному участию в сообществе StackOverflow, а также в отношении этого вопроса.

Я работаю над текстовым пользовательским интерфейсом в C#. У меня есть абстрактный класс window и абстрактный класс control, каждый из которых реализует общую функциональность для типов, которые их наследуют (например, всплывающие окна или элементы управления текстового поля). В настоящее время в программе, которая может реализовать библиотеку, разработчик должен создать объекты window и объекты управления, а затем добавить элементы управления в соответствующие окна и окна в класс диспетчера окон, как это:

var mainWindow = new MainWindow(...);
var textBox1 = new TextBox(...);
mainWindow.AddControl(textBox1);
WindowManager.Add(mainWindow);

Это работает, но это немного неуклюже. Поскольку элемент управления никогда не должен существовать вне окна, я надеялся реализовать типы элементов управления как вложенные типы. Однако, чтобы сохранить расширяемость программы, я хотел бы, чтобы был способ расширить класс window новыми типами элементов управления. Мой вопрос заключается в следующем: Должен ли я использовать отражение или полагаться на разработчиков, использующих классы контейнеров для расширения класса окна? Кроме того, есть ли лучший способ структурировать программу, чем то, как она в настоящее время изложена?

Я также рассматривал использование дженериков, например:

public abstract class Window : DrawableObject, IWindow
{
    public void AddControl <T>(object[] constructorArgs) where T : class, IControl
    {

    }
}

Я стремлюсь к простоте реализации, не жертвуя расширяемостью / рыхлой связью. Заранее спасибо за любые мысли!

EDIT: следует уточнить, основная причина этого заключается в том, чтобы исправить некоторые странности с тем, как Windows и элементы управления сотрудничают. Каждый элемент управления имеет свойство parentWindow, которое используется для доступа к окну, в котором находится элемент управления, для различных целей, таких как создание кнопки выхода для конкретного окна и т.д.

Сейчас это свойство передается конструктору, но мне оно кажется излишним, так как после этого необходимо добавить элемент управления в список элементов управления окна. Я хотел бы найти способ установить это свойство, когда элемент управления добавляется в окно вместо этого, но ограничить это действие только когда элемент управления добавляется, чтобы предотвратить возможные проблемы, если свойство parentWindow изменяется вне этого контекста.

1 ответ

  1. Способ кодирования метода AddControl:

       public void AddControl <T>(object[] constructorArgs)
            where T : class, IControl
       {
       }
    

    Разработчики должны просто указать тип, а метод AddControl создаст его экземпляр с помощью constructorArgs. Этот метод сам по себе неявно заставляет вас использовать отражение. Ни на что другое шансов не остается. Поскольку для добавления элемента управления типа T необходимо создать экземпляр элемента управления типа T. Так как ваш класс Window не имеет понятия о t отражение является единственным решением.
    Для упрощения других подходов может потребоваться рассмотреть несколько перегрузок AddControl.

       public virtual T AddControl <T>()
          where T : class, new(),IControl
       {
            //now you can create instance no reflection required
            var control = new T();
            this.Controls.Add(control);
            return control;
       }
    
       public void AddControl <T>(T control)
          where T : class, IControl
       {
       }
    
       public abstract void AddControl <T>(object[] constructorArgs)
          where T : class, IControl;
    

    Создание абстрактного метода передает onus реализации на дочернем классе и создание нового экземпляра T может быть обработано предполагающий тип T известен там или, по крайней мере, все случаи известных типов того, что T может быть обработаны.
    Это широкая тема, и я думаю, что субъективная. Лучшее использование OOP заключается в том, чтобы достичь дизайна, который соответствует вашей логической цели, что бы это ни было.