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#阻止了这一点,无论如何,您将无法在构造函数中编译自递归。