C#:构造函数调用顺序

时间:2012-08-28 08:59:37

标签: c# constructor

请考虑以下代码:

代码

public class RecursiveConstructor
{
   //When this constructor is called 
   public RecursiveConstructor():this(One(), Two())
   {
       Console.WriteLine("Constructor one. Basic.");
   }

   public RecursiveConstructor(int i, int j)
   {
       Console.WriteLine("Constructor two.");
       Console.WriteLine("Total = " + (i+j));
   }

   public static int One()
   {
       return 1;
   }

   public static int Two()
   {
       return 2;
   }
}

调用方法

public class RecursiveConstructorTest
{
    public static void Main()
    {
        RecursiveConstructor recursiveConstructor = new RecursiveConstructor();

        Console.ReadKey();
    }
}

结果

  

构造函数二。

     

总计= 3

     

构造函数一。基本

为什么第二个构造函数首先运行?

我理解在链式构造函数中我们首先调用基类构造函数然后重新启动链,但是当构造函数保存在同一个类中时,为什么我们仍然会看到这个行为首先调用额外的构造函数?

我原以为最基本的构造函数内容会先执行。

4 个答案:

答案 0 :(得分:7)

我认为编译器运行更安全的方案。 如果你在这里调用另一个构造函数,那么这个其他构造函数可能是你当前构造函数的先决条件。这种行为与调用基础构造函数时暴露的行为一致,然后是预期的。

在创建类的新实例时,有一系列构造函数可以从最不专业的(对象类的构造函数)调用到最专业的(当前类的构造函数)。

运算符:允许您向此链明确添加构造函数,因此此顺序看起来很自然。

答案 1 :(得分:2)

你自己做了解释。它与基本构造函数的调用方式几乎相同。每当在签名中调用构造函数时,比如

 public RecursiveConstructor() : this(One(), Two())

 public RecursiveConstructor() : base()

首先调用:之后的构造函数。

答案 2 :(得分:2)

当您考虑在初始化新对象时始终存在构造函数调用的分层链时,这是有意义的。正如您所说,首先调用基类构造函数。

两种形式的构造函数初始值设定项: base(...),通常被隐含地调用,而: this(...)的行为方式相同。

所以,在你的情况下,我们有一个链:

Object()

...然后

RecursiveConstructor(int i, int j)

...然后

RecursiveConstructor()

答案 3 :(得分:1)

它首先调用构造函数1,但是 ctor1 在它到达ctor1代码块之前调用 ctor2 ,因此你看到了输出。

解决这个问题的一种方法,但保留DRY行为将是重构(int, int)重载:

   //When this constructor is called 
   public RecursiveConstructor()
   {
       Console.WriteLine("Constructor one. Basic.");
       Init(One(), Two());
   }

   public RecursiveConstructor(int i, int j)
   {
       Console.WriteLine("Ctor 2");
       Init(i, j);
   }


   private void Init(int i, int j)
   {
       Console.WriteLine("Refactored");
       Console.WriteLine("Total = " + (i+j));
   }

出于兴趣,以这种方式链接构造函数通常被称为“delegating constructors”。

在Java中,可以将调用放在代码块中的其他构造函数(例如see here),但它必须是块中的第一行