【问题标题】:Extending a class with a new nested class使用新的嵌套类扩展类
【发布时间】:2016-08-27 15:28:35
【问题描述】:

第一个问题,因此我愿意接受有关有效参与 StackOverflow 社区以及与该问题相关的建议。

我正在使用 C# 开发基于文本的 UI。我有一个抽象窗口类和一个抽象控件类,每个类都实现了继承它们的类型的通用功能(例如弹出窗口或文本框控件)。目前,在可能实现该库的程序中,开发人员必须创建窗口对象和控件对象,然后将控件添加到各自的窗口中,并将窗口添加到窗口管理器类中,如下所示:

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

这可行,但有点笨拙。由于控件不应该存在于窗口之外,因此我希望将控件类型实现为嵌套类型。但是,为了保持程序的可扩展性,我希望有一种方法可以使用新的控件类型来扩展窗口类。我的问题是:我应该使用反射,还是依赖开发人员使用容器类来扩展窗口类?或者,有没有比目前的布局更好的方式来构建程序?

我也考虑过使用泛型,例如:

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

    }
}

我的目标是在不牺牲可扩展性/松散耦合的情况下轻松实现。提前感谢您的任何想法!

编辑:应该澄清一下,这样做的主要原因是为了解决 Windows 和控件如何合作的一些奇怪问题。每个控件都有一个 parentWindow 属性,用于访问控件所在的窗口,用于各种用途,例如为特定窗口创建退出按钮等。

现在,这个属性被传递给构造函数,但这对我来说似乎是多余的,因为这样做之后你必须将控件添加到窗口的控件列表中。我想找到一种方法在将控件添加到窗口时设置此属性,但将此操作限制为仅在添加控件时,以防止在此上下文之外更改 parentWindow 属性时出现潜在问题。

【问题讨论】:

  • 我不知道您通过添加该通用方法真正获得了什么。如果我使用它,我希望能够构造我的对象,然后告诉窗口显示它,而不是让窗口为我构造对象。
  • 你是对的。支持激活操作的每种控件类型都将委托ControlAction(IControl source) 作为构造函数参数,并且能够根据来自另一个控件的输入对一个控件执行操作非常有用,如果不能构造和引用控件,这将非常困难窗外。我可以将 ref 返回到创建的控件,但这将是多余的。每个控件还需要一个IWindow parentWindow,所以也许应该在其构造函数代码中将控件添加到其窗口?或者在添加到窗口时设置它的 parentwindow 属性。
  • 在将控件添加到窗口时设置它的父窗口似乎是最有意义的,但我宁愿不公开父窗口的设置器,因为在这种情况下它应该只设置添加到窗口时。不过,我可能只需要解决,让它万无一失可能是愚蠢的差事。

标签: c# generics inheritance reflection types


【解决方案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;

创建一个抽象方法会传递子类上的实现责任,并可以处理创建 T 的新实例,假设 T 的类型在那里已知,或者至少处理 T 可能已知类型的所有情况。 这是一个广泛的话题,我想也是主观的。 OOP 的最佳用途是实现符合您的逻辑目标的设计。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-10
    • 2023-01-10
    • 2019-02-03
    • 1970-01-01
    相关资源
    最近更新 更多