相互实例化两个类中的每一个
本文关键字:两个 每一个 实例化 | 更新日期: 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
创建("实例化")时,它们就变成了实际的对象,应该被这样对待。
您需要重新考虑您的策略,而不是简单地引用一个Min
或CoundownUserControl
对象。每一个代表什么?您建议UserControl
(Form
的一部分)需要为它创建自己的Form
-事实并非如此。Form
是创建 UserControl
的对象。UserControl
可以通过ParentForm
属性访问Form
。
当你这样做:new Min()
时,你正在创建一个新的Min
对象。然后,在Min
中,当您这样做:new CountdownUserControl()
时,您正在创建一个新的CoundownUserControl
对象。然后创建一个新的Min
对象,依此类推。
如何解决您的问题
简单地说,如果您确定用户控件位于类型为Min
的Form
上,则在用户控件中使用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之间共享。