【问题标题】:Derived Class instantiates 2 objects of BASE Class派生类实例化 BASE 类的 2 个对象
【发布时间】:2020-06-10 10:19:26
【问题描述】:

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

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 ```

【问题讨论】:

  • 您创建了 4 个对象:instancen1n2n3 - 那么您为什么希望只有 1 个对象?
  • "如果没有自己的构造函数,将调用基类构造函数" - 每个派生类总是必须调用其基类的构造函数以确保它具有被正确构建。派生类是否提供用户定义的构造函数并不重要
  • 尝试在 private static readonly Base1 instance = new Base1(); 之前移动 private static int numInstance = 0; - 这似乎可以解决问题,尽管我不确定原因(以及语言标准对此有何规定)
  • 注意:调用基本构造函数不是创建另一个对象 - 派生类型的实例(单个)对象
  • 谢谢,错字抱歉。后面提到了派生类实例。但是我很困惑为什么在创建基类的第一个对象后连续调用创建派生类实例时 numInstance 没有更改为 1。 (实例)。

标签: c# linqpad


【解决方案1】:

您的输出令人惊讶的原因来自以下几行

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-28
    • 2015-03-23
    • 1970-01-01
    • 2023-02-03
    • 2014-10-13
    • 2021-08-12
    相关资源
    最近更新 更多