c# - 派生类实例化 BASE 类的 2 个对象
问题描述
我有一个基本的查询。我有一个空的派生类。我注意到,当我运行下面粘贴的一段代码(在 Linqpad 中运行)时,我最终得到了 4 个 BASE 类的对象。我的理解是,当我们实例化一个派生类对象时,在没有它自己的构造函数的情况下,会调用 BASE 类构造函数,从而产生 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{
}
该代码产生了派生类的 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)(强调我的)
[...]当一个类被初始化时,该类中的所有静态字段首先被初始化为其默认值,然后静态字段初始化程序以文本顺序执行
因此,您的代码首先创建instance
,将其设置numInstances
为 1,然后执行numInstance = 0;
将字段“重置”为0
.
将声明的顺序更改为
private static int numInstance = 0;
private static readonly Base1 instance = new Base1();
产生您期望的结果,因为numInstances
在您构造第一个实例之前首先初始化为 0(技术上两次)。或者,您也可以只删除初始化程序,numInstances
因为默认值为int
0 反正
推荐阅读
- mysql - Visual studio is restarting as I hit the required URL
- google-sheets - 在 Google 表格中加入条件转置
- text-to-speech - Azure 认知服务 TTS 自定义语音终结点测试
- laravel - Laravel PHPUnit PhpStorm Docker 连接
- python - Python程序读取文本文件,然后将其内容写入另一个文件,具有不同大小的边距,由用户输入
- javascript - 在嵌套方法中更新模型时,AngularJS 视图不会刷新
- sql - 如何在查询中包含公司名称
- java - 根据我当前的位置每秒更新文本视图
- javascript - 使用行计数器函数 increment() 和函数 parse() 清除两个文本区域
- javascript - 如何从数据库中检索数据并将其显示在选择下拉列表中