Derived Class 实例化 BASE Class 的 2 个对象

Derived Class instantiates 2 objects of BASE Class

我有一个基本的查询。我有一个派生的 class 是空的。我注意到,当我 运行 下面粘贴的一段代码(Linqpad 中的 运行s)时,我最终得到了 BASE Class 的 4 个对象。我的理解是,当我们实例化派生的 class 对象时,在没有自己的构造函数的情况下,将调用 BASE Class 构造函数,从而导致派生的 class.[=14= 的 1 个实例]

void Main()
{

  NestedS n1 = new NestedS();   
  NestedS n2 = new NestedS();    
  NestedS n3 = new NestedS(); 


}

public class Base1
{

private static readonly Base1 instance = new Base1();
private static int numInstance = 0;
private readonly object lock1 = new object();

public Base1()
{

 lock(lock1) 
 {
  numInstance.Dump("before");
  numInstance++;
  numInstance.Dump("here");
  }
}

}

public  class NestedS : Base1{

}

代码生成派生的 class 的 4 个实例。有人可以向我解释一下背后的原因吗。

更新: 抱歉,在这里改写我的查询,并粘贴输出。从输出来看,numInstance 应该在创建第二个实例之前就已经初始化为 1,但在创建第二个实例时它仍然是 0:

before

0 


here

1 


before

0 


here

1 


before

1 


here

2 


before

2 


here

3 ```

你的惊人输出的原因来自行

private static readonly Base1 instance = new Base1();
private static int numInstance = 0;

语言标准说的是字段初始值设定项 (https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#variable-initializers)(强调我的)

[...] when a class is initialized, all static fields in that class are first initialized to their default values, and then the static field initializers are executed in textual order

因此您的代码首先创建 instance,它将 numInstances 设置为 1,然后 执行行 numInstance = 0; "resetting" 0.

字段

将声明的顺序更改为

private static int numInstance = 0;
private static readonly Base1 instance = new Base1();

产生您期望的结果,因为 numInstances 在您构造第一个实例之前首先被初始化为 0(技术上是两次)。或者,您也可以只从 numInstances 中删除初始值设定项,因为 int 的默认值无论如何都是 0