在构造之前发送对象的引用

use*_*434 63 c# constructor reference

我在其中一个应用程序中看到了以下代码:

public class First()
{
      private Second _second;

      public First()
      {
          _second = new Second(this);
          // Doing some other initialization stuff,
      }

}

public class Second
{
    public Second(First f)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

First()构造函数中,我们First() 完全构造之前发送类的引用并不是很糟糕吗?我认为只有在控制逻辑离开构造函数时,对象才会完全构造.

或者这没关系?

Jon*_*eet 70

我的问题是,在First()构造函数中,我们在完全构造之前发送类First()的引用并不是很糟糕吗?

有些.当然,这可能是一个问题.

如果Second构造函数只是保留了一个引用供以后使用,那就不算太糟糕了.另一方面,如果Second构造函数调用回First:

public Second(First f)
{
    f.DoSomethingUsingState();
}
Run Code Online (Sandbox Code Playgroud)

......而且还没有建立国家,那当然是一件非常糟糕的事情.如果你打电话给虚拟方法First那么它可能会更糟 - 你最终可能会调用一些甚至没有机会运行任何构造函数体的代码(尽管它的变量初始化器已被执行).

特别是,readonly字段可以首先看到一个值,然后再看另一个...

我不久前在博客上发表了这篇文章,可能会提供更多信息.

当然,如果不做这种事情,很难创建两个相互引用的不可变对象......


Dan*_*ant 17

如果您遇到此模式,您可能会检查是否可以将其重构为:

public class First()
{
      private Second _second;

      public First()
      {
          _second = new Second(this);
          // Doing some other initialization stuff,
      }

      private class Second
      {
          public Second(First f)
          {
          }
      }
}
Run Code Online (Sandbox Code Playgroud)

将依赖项传递给构造函数意味着两个类之间存在紧密耦合,因为First必须相信Second知道它在做什么,并且不会尝试依赖于First的未初始化状态.当Second是私有嵌套子类(因此是明确的实现细节)时,或者当它是内部类时,这种强耦合更合适.


Jus*_*ner 11

答案是,这取决于.但一般来说,由于潜在的后果,这被认为是一个坏主意.

更具体地说,只要在构建之前Second实际上没有使用任何东西First,那么你应该没问题.如果你不能保证不知何故,你肯定会遇到问题.