C# 类的这种递归构造是如何工作的?

C# 类的这种递归构造是如何工作的?,c#,constructor,C#,Constructor,我正在读《简而言之》,有一段代码我想不起来: class Foo { public static Foo Instance = new Foo(); public static int X = 3; Foo() { Console.WriteLine(X); } } class Program { static void Main() { Console.WriteLine(Foo.X); Foo myfoo

我正在读《简而言之》,有一段代码我想不起来:

class Foo 
{
    public static Foo Instance = new Foo();
    public static int X = 3;
    Foo() {
       Console.WriteLine(X);
    } 
}


class Program
{
  static void Main() { 
      Console.WriteLine(Foo.X); 
      Foo myfoo = new Foo();
      Console.WriteLine(Foo.X);
  }
}
问题:当我们调用构造函数“Foo myfoo=new Foo()”时,会发生什么步骤?这个计划不是注定要失败吗

public static Foo Instance = new Foo();

关键字表示它属于类型而不是对象。

您提供的代码片段在main中显示您正在从
Foo
类打印
X
变量三次

第二行创建了
foo
实例,尽管您没有在其他任何地方使用它

注意,您的第三行是
Console.WriteLine(Foo.X)
如果您想使用从构造函数接收到的结果(在创建foo对象(第2行)的过程中会进行初始化),那么您必须使用Console.WriteLine(Myfoo.X)

我希望您的应用程序的输出为:

3
3
3

根本没有递归。事实上,这是一个众所周知的模式,称为“”

实际上,代码甚至不会编译。构造函数是私有的(默认值为
private
),因此创建
Foo
实例的唯一可能方法是位于
Foo
类本身内部,这是通过以下方式完成的:

public static Foo Instance = new Foo();

因此,基本上这段代码公开了
Foo
公共静态
实例,您不能构造任何其他实例,因为您不能从
Foo
类本身外部调用构造函数。

看起来像一个单例,静态Foo实例“instance”将与所有项目相同,因此它不是“递归的”,如果它不是静态的,是的,你会遇到麻烦,因为分配无限个“Foo”实例会吃掉你所有的ram,但是因为只有一个实例被共享,所以代码没有问题。首先,它不会编译,因为构造函数不是公共的

其次,不,这不是注定的,它只是意味着将有两个Foo实例被构建

第一个实例是创建对Foo的静态引用时。这将调用构造函数并输出0,因为代码尚未初始化静态变量X

构造函数将再次被调用以构造Foo的第二个实例,但这次静态变量将被设置为3,因此控制台输出将为3

就这样

正如其他人所注意到的,构造函数是私有的,以强制执行singleton模式。因此,应该通过静态类变量访问实例

Foo foo = Foo.Instance;

这样做的问题是,当静态变量X输出到控制台时,它将是0,因为实例的构造在X的初始化之前。

在什么意义上注定?实例的构造!=类初始化。在哪里可以看到递归?构造函数是私有的,所以
myFoo=newfoo()
将不会编译。我宁愿将
readonly
添加到字段:
公共静态readonly Foo Instance=new Foo();
我认为输出将是0;3;3;3,因为第一个实例(静态实例)将在分配静态int值之前创建……您的意思是实际上是“Instance=new Foo();”行在整个程序中只执行一次?因为它是一个静态字段,对吗?它会占用堆栈,而不会占用额外的ram,导致StackOverflowException。但是c#阻止了这一点,无论如何,您将无法在构造函数中编译自递归。