我有一个基本查询。我有一个空的派生类。我注意到,当我运行下面粘贴的代码段(在 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://learn.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;
将字段“重置”为 0
。
将声明的顺序更改为
private static int numInstance = 0;
private static readonly Base1 instance = new Base1();
产生您期望的结果,因为在构造第一个实例之前,numInstances
首先被初始化为 0(技术上是两次)。或者,您也可以从 numInstances
中删除初始化程序,因为 int
的默认值无论如何都是 0
关于c# - 派生类实例化 BASE 类的 2 个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62301152/