派生类实例化了2个BASE类的对象。

问题描述 投票:0回答:1

我有一个基本的查询。我有一个派生类,这个类是空的,我注意到当我运行下面粘贴的代码(在Linqpad中运行)时,我最终得到4个BASE类的对象。我注意到,当我运行下面粘贴的代码(在Linqpad中运行)时,我最终得到4个BASE类对象。我的理解是,当我们实例化一个派生类对象时,在没有自己的构造函数的情况下,BASE类的构造函数会被调用,从而产生一个派生类的实例。

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{

}

这段代码的结果是派生类有4个实例。谁能给我解释一下这背后的原因。

更新:对不起,在这里重新表述我的疑问,把输出也粘贴过来。从输出来看,numInstance应该在第二个实例创建之前就已经被初始化为1了,但是在第二个实例创建的时候还是0。

before

0 


here

1 


before

0 


here

1 


before

1 


here

2 


before

2 


here

3 ```

c# linqpad
1个回答
3
投票

你的惊人输出的原因来自于以下几行代码

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

语言标准中提到了字段初始化器(https:/docs.microsoft.comen-usdotnetcsharplanguag-referencelanguag-specificationclasses#variable-initializers。)(重点是我)

[...]当一个类被初始化时,该类中的所有静态字段首先被初始化为它们的默认值,然后静态字段初始化器被执行。语序

所以你的代码首先创建了 instance,其中规定 numInstances 至1和 之后 执行该行 numInstance = 0; "重置 "该字段为 0.

将声明的顺序更改为

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

产生了你所期待的结果,如 numInstances 在构造第一个实例之前,首先被初始化为0(技术上说是两次)。或者,你也可以直接从 numInstances 的默认值,作为 int 反正是0

© www.soinside.com 2019 - 2024. All rights reserved.