【问题标题】:How can I avoid passing a reference to a parent object when constructing a new instance of a class?在构造类的新实例时,如何避免传递对父对象的引用?
【发布时间】:2012-07-21 11:00:11
【问题描述】:

我有两个类定义如下。

第一个:

internal class Content {

   internal Content(Master master) {
        // code omitted
   }

// code omitted
}

第二个:

public class Master {

     internal Content content { get; set; }

     internal Master() {
         // code omitted
     }

// code omitted
}

将 Content Class 公开为 Master 的属性我需要执行以下操作:

Master M = new Master(); 
M.content = new Content(M); 

有没有办法不通过Content Constructor中的Master(M)?

【问题讨论】:

  • 如果您可以控制内容的来源,您可以按照自己的方式进行更改。但是为什么你不想在构造函数中传递Master呢?
  • @Luca:请看一下,我已经提供了一个答案,它保持了两个类的依赖关系,同时允许轻松实例化。

标签: c# class object constructor


【解决方案1】:

为什么不使用惰性初始化 idom?

public class Master
{
    private Content _content;

    internal Content content
    {
        get
        {
            if (_content == null)
            {
                _content = new Content(this);
            }
            return _content;
        }
    }
}

如果Master 总是必须设置content 属性,则在构造期间创建Content 成员:

public class Master
{
    internal Content content
    {
        get; private set;
    }

    internal Master()
    {
        content = new Content(this);
    }
}

您也可以使用混合方法:

public class Master
{
    internal Content content
    {
        get; private set;
    }

    internal Content GetOrCreateContent()
    {
        if (content == null)
        {
            content = new Content(this);
        }
        return content;
    }

    internal Master()
    {
    }
}

【讨论】:

  • 但是你仍然需要在这里将 Master 实例传递给 Content 的构造函数。
  • @PiotrJustyna:是的,但这完全是内部的,与客户端代码无关/不可见。它也很干净且定义准确。
  • @leppie:这就是这里的有趣之处。问题明确指出:有没有办法不将该实例传递给 Content 构造函数?
  • @PiotrJustyna:那我误解了。我以为您的意思是“不要将实例传递给客户端代码中的 Content 构造函数”。它的内部组织方式并不重要。
  • @gwiazdorr 我喜欢这种方法,但我不想在创建 Master 时总是实例化 Content。也许我需要实例化一个没有内容的大师。谢谢。
【解决方案2】:

大概是Content 需要 Master ?实际上,构造函数是一种很好的管理方式,但如果这是一个问题,你也可以这样做:

internal class Content {
    internal void SetMaster(Master master) {this.master = master; }
    //...
}
internal class Master {
    internal void SetContent(Content content) {
        if(content == null) throw new ArgumentNullException("content");
        // maybe handle double-calls...
        this.content = content;
        content.SetMaster(this);
    }
}
...
Master M = new Master();
M.SetContent(new Content());

或者让Master 默认创建Content。不过,坦率地说,我会保持“原样”,直到出现真正的“这是个问题”。

【讨论】:

    【解决方案3】:

    由于未显示类中的代码,因此我必须对您打算做什么做出一些假设。正如我从您的代码中看到的那样,Content 需要MasterMaster 不能没有Content

    使用我为您制定的解决方案,您可以执行以下操作:

    void Main()
    {
        Master M1 = new Master(); // content instantiated implicitly
        Master M2 = new Content().master; // master instantiated implicitly
    }
    

    因此,您可以在实例化 MasterContent 内实例化,反之亦然:实例化 ContentMaster 被隐式实例化。

    无论您选择了哪种替代方案:相应的其他对象始终通过属性变量实例化并可用。

    本例中的类定义如下:

    internal class Content  {  
    
        internal Master master { get; set; }
    
        internal Content(Master pmaster) {     
            master=pmaster;
        }
    
        internal Content() {     
            master = new Master() { content = this };
        }  
    }
    
    public class Master {  
    
        internal Content content { get; set; }  
    
        internal Master() {     
            content = new Content(this);
        }  
    
        // this is optional and can be omitted, if not needed:  
        internal Master(Content pcontent) {     
            content = pcontent;
        }  
    } 
    

    请注意,我尽可能地保留了您在问题中给出的结构,而您现在拥有额外的灵活性。

    【讨论】:

      猜你喜欢
      • 2010-11-03
      • 1970-01-01
      • 2013-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-21
      • 1970-01-01
      • 2013-06-04
      相关资源
      最近更新 更多