相互实例化两个类中的每一个

本文关键字:两个 每一个 实例化 | 更新日期: 2023-09-27 18:04:56

我有一个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。有人知道解决这个问题的方法吗?谢谢你的宝贵时间。

相互实例化两个类中的每一个

类和方法

类不应该仅仅被看作是方法的集合,当它们被new创建("实例化")时,它们就变成了实际的对象,应该被这样对待。

您需要重新考虑您的策略,而不是简单地引用一个MinCoundownUserControl对象。每一个代表什么?您建议UserControl (Form的一部分)需要为它创建自己的Form -事实并非如此。Form创建 UserControl的对象。UserControl可以通过ParentForm属性访问Form

StackOverflow

当你这样做:new Min()时,你正在创建一个新的Min对象。然后,在Min中,当您这样做:new CountdownUserControl()时,您正在创建一个新的CoundownUserControl对象。然后创建一个新的Min对象,依此类推。

如何解决您的问题

简单地说,如果您确定用户控件位于类型为MinForm上,则在用户控件中使用Min min = (Min)this.ParentForm;

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

所有这些答案都很棒,但您也应该考虑循环依赖关系通常很难处理的事实。您的类应该是具有单一目的的独立单元。它们之间应该是松散耦合的。如果您重新设计您的类以消除循环依赖并遵循这些指导原则,那么您通常会编写出更好且更易于维护的代码,并且首先会出现更少的此类问题。

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

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

当你面对这些问题时,可能是你的类结构出了问题。也许您可以将一些功能从类中分离出来,放到一个新的类中,以避免这个问题。

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

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

CountdownUserControl将在表单最小?为什么要从控件实例化表单,而不是相反?倒计时控件不应该在表单上吗?然后可以实例化表单,初始化控件,然后访问函数。

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

解决方案是将CountdownUserControl的实例注入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);
    }

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

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);
    }

更合适的解决方案是从两个类中分离出公共功能,并将它们放在单独的类中。仔细阅读单一责任原则。我的博客上有一篇关于它的文章

你可以把CountdownUserControl的一个实例传递给你的Min类(通过一个额外的构造函数参数或通过一个属性)

public partial class Min: Form {
    public Min() {
        InitializeComponent();
    }
    public CountdownUserControl Countdown {get;set;}
}

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

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

如前所述,如果您计划在表单中显示用户控件,那么应该采用不同的解决方案。但这完全取决于你如何计划你要对表单做什么。例如,如果你在一个对话框中显示表单,保持类级引用是一个坏主意,因为一旦关闭,表单将被处理。

多一点细节会让你更接近完全正确的答案。

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

真的有必要提到的函数是CountdownUserControl的成员吗?

你能透露更多你的类的公共接口吗?如果函数没有引用CountdownUserControl的实例,考虑将其更改为static。否则尝试设计一个新的类,例如CountdownState,它的实例可以在CountdownUserControl和Min之间共享。