gpt4 book ai didi

c# - 在 C# winforms 中消除继承 "magic"的最佳方法?

转载 作者:行者123 更新时间:2023-11-30 16:15:51 24 4
gpt4 key购买 nike

我正在处理一个遗留应用程序,它由于继承而存在一些缺陷,但我正在努力正确地解决它。

目前 WinForms 的结构如下所示:

  • BaseForm
  • ListViewForm : BaseForm
  • ListViewFormReadOnly : ListViewForm
  • ListViewFormWithDetailForm : ListViewForm
  • DetailForm : BaseForm
  • ConcreteForm : ListViewFormWithDetailForm

在 BaseForm 中有一个名为 sth 的方法 protected virtual void InitializeMyStuff()在继承的实例中被覆盖。

例如

public class BaseForm {
public BaseForm() {
//.. do stuff

//.. do other stuff like initialize DB connection or read app.config values and initialize properties..
}

public virtual void InitializeMyStuff() {
throw new NotImplementedException();
}
}

public class ListViewForm : BaseForm {
protected BindingSource GridBindingSource { get; set; }

public ListViewForm {
//do special stuff like adding the grid and some buttons
}
}
public class ConcreteForm : ListViewForm {
public override void InitializeMyStuff() {
GridBindingSource = my_bindingSource;
SomeOtherUsefulProperty = myValue;
Foo = new Bar();
// etc.
}
}

//Usage:
var myForm = new ConcreteForm();
myForm.InitializeMyStuff();

您可以想象这会产生一些问题,例如:- “此时我必须设置哪些内容才能使表格正常工作”- “哪些东西可能还没有初始化?”- “我可以使用哪些属性和方法调用”以及关于那个神奇黑匣子中可能发生的事情的其他一些有趣的想法。

我如何重构它,以便更清楚地了解正在发生的事情?请记住,这是一个包含大约 150 个或更多具体形式的项目。

我最初的想法是封装那些神奇的属性,比如 GridBindingSource例如放入一个对象(例如 FormConfiguration )并在 BaseForm 中将其设为私有(private).

例如类似的东西

public class BaseForm {
private FormConfigObject _formConfig = new FormConfigObject();

protected override void OnLoad()
{
InitializeMyStuff(_formConfig);
}

protected virtual void InitializeMyStuff(FormConfigObject config)
{}
}

我在这里遇到的问题是:ListForm 的 FormConfig 对象必须具有其他属性,例如 GridBindingSource。但我不能只将派生类中的签名更改为 ListFormConfigObject代替 FormConfigObject ..

谁能提出摆脱这种困境的可能解决方案?

//编辑:将代码理顺到实际发生的情况,并消除构造函数违规中的虚拟调用。

最佳答案

主要问题是:BaseForm 中是否有任何对象:

  • 需要在BaseForm的构造函数中初始化
  • 取决于子类的具体实现

如果存在这样的对象,那么它们可能应该是多态的,并从子类传递到 BaseForm 的构造函数中。

许多可能场景中的一个简单示例:

abstract class RandomPicture
{
public RandomPicture()
{
shapes = new List<Shape>();
InitializeRandomShapes();

// do some initial drawing calculations
}

protected abstract void InitializeRandomShapes();

protected List<Shape> shapes;
}

//... subclasses initialize the shapes

这可以更改为:

abstract class RandomPicture
{
public RandomPicture(AbstractShapeCollection shapeCollection)
{
shapes = shapeCollection;

// do some initial drawing calculations
}

private AbstractShapeCollection shapes;
}

现在子类通过抽象对象提供所需的信息,因此基类可以继续执行它的任务。

像这样将信息拆分到各种对象中是一个很好的重构开始,因为您创建了更多更小的对象,更容易测试和管理并揭示您遇到的困惑的底层结构。它还有助于减少违反 Single Responsibility Principle 的次数.

关于c# - 在 C# winforms 中消除继承 "magic"的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19114122/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com