c# - 派生类实例化 BASE 类的 2 个对象

标签 c# linqpad

我有一个基本查询。我有一个空的派生类。我注意到,当我运行下面粘贴的代码段(在 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/

相关文章:

c# - 覆盖 RichEditBox 上的键盘快捷键?

c# - 使用 LINQ to SQL 搜索整个数据库

c# - 为什么 DatasourceRequest 没有传递到 Kendo Grid 中工具栏的自定义命令

c# - 嵌套 linq 查询中的“列名 [ColumnName] 无效”

mysql - LinqPad v4.31.0 和 IQ Driver 2.0.2 出现握手错误?

c# - LINQPad索引超出范围异常

c# - 使用 Open XML SDK 流式传输 Excel 数据

c# - 匿名 JSON 对象集合的单元测试

c# - 在 LINQPad 中使用 Dump() 扩展方法和使用 Console.WriteLine() 有什么区别?

c# - 任务和线程不在 Linqpad 的静态构造函数中运行