彼此实例化两个类中的每一个

时间:2011-08-10 12:15:38

标签: c# .net winforms class class-design

我有一个C#类问题,我希望能得到一些帮助。我有一个名为CountdownUserControl的类。这个类中有许多功能。然后我又有一个叫Min的课。在CountdownUserControl类中,我在这种形式中需要一些东西,所以我在CountdownUserControl中创建了它的一个实例:

public partial class CountdownUserControl : UserControl
{
    //-----------------------------------------------
    // Private data members
    //-----------------------------------------------
    private Min _Min = new Min();

然而在Min类中我也想使用CountdownUserControl类中包含的函数 - 但是我不能在Min类中创建它的实例,例如

public partial class Min : Form
{
    private CountdownUserControl CU = new CountdownUserControl();

所以在Min课程中我可以做CU.Method_I_want();

因为这将给出stackoverflow。有没有人知道这个解决方案?谢谢你的时间。

9 个答案:

答案 0 :(得分:3)

类和方法

当使用new创建('实例化')类时,不应将类视为方法集合,它们将成为应被视为实际对象的实际对象。

您需要重新考虑您的策略,而只需引用 MinCoundownUserControl对象。每个代表什么?您建议UserControlForm的一部分)需要为其创建自己的Form - 事实并非如此。 Form创建 UserControl的对象。 UserControl可以使用Form属性访问ParentForm

StackOverflow

执行此操作时:new Min()您正在创建新的Min对象。然后,在Min中,当您执行此操作时:new CountdownUserControl()您正在创建一个新的CoundownUserControl对象。这又会创建一个新的Min对象,依此类推。

如何解决您的问题

如果您确定用户控件位于类型为Min min = (Min)this.ParentForm;的{​​{1}}上,请在用户控件中使用Form

最后/另外,除非您要设置属性并将其添加到代码中表单的Min集合中,否则不应自己创建CountdownUserControl的实例。相反,构建项目,将Controls拖放到表单上 - 将自动在CountdownUserControl类上创建一个访问控件的属性,称为Min

答案 1 :(得分:1)

肯定有很多解决方案。一个简单的方法是将当前Min传递给其构造函数中的CountdownUserControl(反之亦然):

private Min min;
public CountdownUserControl(Min min)
{
     this.min = min;
}

当你遇到这类问题时,你的班级结构可能有问题。也许您可以将类中的一些功能拆分成新的功能以避免此问题。

答案 2 :(得分:1)

所有这些答案都很棒,但您也应该考虑cyclic dependencies通常很难处理的事实。你的课程应该是一些有single purpose的孤立单元。他们彼此应该loosely coupled。如果你重新设计你的类以消除循环依赖并遵循这些指导原则,你将编写更好,更易维护的代码,并且首先会有更少的问题。

答案 3 :(得分:0)

不是每次都实例化一个新的Min类,而是可以在构造函数中设置它的值。

public CountdownUserControl(Min min)
{
     _Min = min;
...

答案 4 :(得分:0)

CountdownUserControl会出现在Form Min上吗?为什么要从控件中实例化表单,而不是相反?倒计时控制不应该在表格上吗?然后,您可以实例化表单,初始化控件,然后访问该函数。

答案 5 :(得分:0)

不要在用户控件中创建表单。将其添加为依赖项:

public partial class CountdownUserControl : UserControl
{
    private Min _Min;

    public CountdownUserControl(Min parentForm);

然后在表单中使用它:

public partial class Min : Form
{
    private CountdownUserControl CU;

    public Min()
    {
       CU = new CountdownUserControl (this);
    }

<强>更新

更合适的解决方案是从两个类中分解常用功能并将它们放在单独的类中。阅读单一责任原则。我在blog发了一篇关于它的帖子。

答案 6 :(得分:0)

您可以将CountdownUserControl的实例传递给Min类(通过其他构造函数参数或通过属性)。

public partial class Min: Form {
    public Min() {
        InitializeComponent();
    }

    public CountdownUserControl Countdown {get;set;}
}

由于这是一个表格,您可能希望使用该属性,以免破坏设计师。

我不会说这是否是正确的形式(希望你使用像PresentationModel或MVC这样的东西),因为我知道tehre是需要这样的时间代码。

现在已经指出,如果您打算在表单中显示用户控件,则应采用不同的解决方案。但这一切都取决于你如何计划你在表单上做什么。如果您在对话框中显示teh表单,保持类级别引用是一个坏主意,因为一旦关闭,表单将被处理。

更多细节可以让您更接近完全正确的答案。

答案 7 :(得分:0)

  

然而在Min类中我也想使用CountdownUserControl类中包含的函数 - 但是我不能在Min类中创建它的实例,例如

提到的功能是否真的有必要是CountdownUserControl的成员?

你能透露一下你班级的更多公共界面吗? 如果函数没有引用CountdownUserControl的实例,请考虑将其更改为static。否则尝试设计一个名为eg的新类CountdownState,其实例可以在CountdownUserControl和Min。

之间共享

答案 8 :(得分:0)

这里的问题是,无论何时创建CountdownUserControl,它都会尝试创建新的Min,但每当创建新的Min时,它会尝试创建新的CountdownUserControl CountdownUserControl 1}}。这个过程可以无限期地继续下去,因此堆栈被烧毁了。

解决方案是将Min的实例注入CountdownUserControl(反之亦然,具体取决于首先创建的内容)。

所以public partial class CountdownUserControl : UserControl { //----------------------------------------------- // Private data members //----------------------------------------------- private Min _Min; public CountdownUserControl(Min min) { _Min = min; } 看起来像这样:

Min

...而public partial class Min : Form { private CountdownUserControl CU; public Min() { CU = new CountdownUserControl(this); } 将如下所示:

{{1}}