Stackoverflow - 使用构造函数和初始值设定项的两个类之间的无限递归

本文关键字:两个 递归 无限 之间 构造函数 Stackoverflow | 更新日期: 2023-09-27 18:37:25

我有一点问题,不确定如何解决这个问题。 我有两个名为DatabaseManagementgment和Logger的类,它们相互引用。 但是,由于无休止的递归,我得到了堆栈溢出错误。 由于我在 DatabaseManagement 中创建 Logger 的实例,并在 Logger 类中创建 DatabaseMangement 的实例,因此程序在每个类之间无休止地运行,直到失败。 我在下面放了代码示例。 这两个类的功能相互依赖。 如何在没有递归的情况下引用另一个类?

数据库管理器

class DatabaseManagement
{
    Logger l = new Logger();
    public MySqlConnection myconn { get; private set; }
    public void OpenDatabases()
    {

记录

class Logger
    {
        DatabaseManagement dm = new DatabaseManagement();
        public void createLogEntry(char logType, string message)
        {

Stackoverflow - 使用构造函数和初始值设定项的两个类之间的无限递归

我认为

这应该可以解决问题。整洁的东西:没有静电。

您需要做的唯一真正的"技巧"是将this(当前对象的实例,在本例中为 DatabaseManagement 的实例)传递给 Logger 的构造函数。

class DatabaseManagement
{
    private Logger _logger;
    public DatabaseManagement()
    {
        _logger = new Logger(this);
    }
}
class Logger
{
    DatabaseManagement _dm;
    public Logger(DatabaseManagement dm)
    {
        _dm = dm;
    }
}

这应该可以解决您的问题:

public class DatabaseManagement
{
   Logger logger;
   // Other properties and fields
   public DatabaseManagement()
   {
     this.logger = new Logger(this);
     // Other constructor stuff
   }
   // Other methods
}
public class Logger
{
  DatabaseManagement dbManagement;
  // Other properties and fields
  public Logger(DatabaseManagement dbManagement)
  {
    this.dbManagement = dbManagement;
    // other constructor stuff
  }
  // Other methods
}

仅供参考,这种模式称为Constructor Injection.

您还可以在需要使用/调用其中一个类时使用属性来获取单例:

class DatabaseManagement
{
    private static DatabaseManagement _instance;
    public static DatabaseManagement Inst {
        // Return _instance, but make it a new DatabaseManagement() if null:
        get { return _instance ?? (_instance = new DatabaseManagement())}
    }
    ...
}
class Logger
{
    private static Logger _instance;
    public static Logger Inst {
        get { return _instance ?? (_instance = new Logger())}
    }
    ...
}

现在,您几乎可以从任何地方调用其中任何一个,如下所示,并且知道您将始终使用单个实例:

Logger.Inst.SomeMethod();
DatabaseManagement.Inst.SomeMethod();