Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否在C#中调用空构造函数?_C#_Constructor - Fatal编程技术网

是否在C#中调用空构造函数?

是否在C#中调用空构造函数?,c#,constructor,C#,Constructor,给定一个空构造函数,例如: internal C() { } 是否需要创建对象?它应该只包含一个返回操作,所以在理论上,它可以被丢弃,对吗 注意:我很清楚,对于每个类,都存在一个隐式构造函数。然而,这个问题的意图是:;如果CLR以独占方式调用构造函数,则返回操作。总是在对象实例化时调用构造函数,即使它是无参数且为空的。如果您不编写任何构造函数,编译器会隐式地为您生成一个默认构造函数 这是为了让您能够在以后编写构造函数,而无需重新编译任何调用代码 由于这个原因,对象实例化总是调用构造函数,除了像

给定一个空构造函数,例如:

internal C()
{
}
是否需要创建对象?它应该只包含一个返回操作,所以在理论上,它可以被丢弃,对吗

注意:我很清楚,对于每个类,都存在一个隐式构造函数。然而,这个问题的意图是:;如果CLR以独占方式调用构造函数,则返回操作。

总是在对象实例化时调用构造函数,即使它是无参数且为空的。如果您不编写任何构造函数,编译器会隐式地为您生成一个默认构造函数

这是为了让您能够在以后编写构造函数,而无需重新编译任何调用代码

由于这个原因,对象实例化总是调用构造函数,除了像这样的边缘情况,这是我所知道的唯一不用调用构造函数就实例化对象的方法(它用于序列化目的)

顺便说一下,IL操作码(用于实例化新对象)显式地将构造函数作为输入参数:

newobj
指令创建新对象或值类型的新实例。Ctor是元数据标记(必须标记为构造函数的methodref或methoddef),指示要调用的构造函数的名称、类和签名

newobj
指令分配与ctor关联的类的新实例,并根据需要将新实例中的所有字段初始化为
0
(正确类型)或空引用。然后,它使用给定的参数和新创建的实例调用构造函数。调用构造函数后,现在初始化的对象引用(类型O)被推送到堆栈上

因此,要创建的类型实际上是由要调用的构造函数标识的,而不是由类型标记本身标识的,这使得构造函数是必需的


由于您想知道JIT的作用,下面是在发布模式下对以下行的反汇编(
SomeClass
是一个默认构造函数为空的类):

x64:

x86:


好的,我对汇编代码不是很熟练,但是x64版本执行两个调用。我假设第一个是分配,第二个是构造函数调用,但我不确定这一点(由于某种原因,VS不会让我访问这些地址)。x86代码中的第三个(间接的)
调用
令我惊讶,我不知道它的用途。

不,如果不提供,默认构造函数将被隐式调用。创建对象时,传递构造函数时
nextobjpointer
指向当前对象引用

否,不应丢弃构造函数,因为它似乎是类的作者希望仅从其声明程序集中实例化它(通过将构造函数标记为
internal
).

是,在每次对象创建时都会调用它,因为它是默认构造函数。如果没有任何其他参数化构造函数,则可以忽略它,但如果使用其他构造函数,则需要指定默认构造函数。有关更多信息,请参见

不管您是否编写构造函数。每次声明任何类的对象时,都将撤销构造函数

现在您可以显式地使用这个构造函数来完成一些工作

或者你可以把它留为空白,甚至不在课堂上写


保持空白和不编写构造函数是完全相似的。

为什么不调用它?@Lucastzesniewski-我不认为不应该通过定义调用它,但我怀疑优化。对象层次结构中的每一层都需要调用构造函数。如果不显式地执行,它将为您完成。C#编译器将发出IL来调用它,但抖动可能会优化它。这个问题背后的原因是什么?你是清洁代码吗?你是从C#spec的角度问的吗?这可能是对的,但是CLR实现是否同意?你自己检查一下。您将无法在程序集外部创建该类型的新实例。但是外部汇编仍然可以引用它。
空构造函数总是被称为
?如果我有带参数的构造函数和显式空构造函数,为什么要从带参数的构造函数调用它@这不是我的意思,我把我的措辞弄错了,我将改写这句话来澄清。这些信息通常是可靠的,但它没有考虑JIT编译。JIT编译器完全可以改变虚拟指令的规则。@toplel32我已经在答案中添加了汇编代码,因为您似乎对此感兴趣。让我们看看是否有比我更熟悉汇编程序的人可以对此发表评论。
var inst = new SomeClass();
000007FE95A30093  in          al,dx  
000007FE95A30094  and         byte ptr [rax-73h],cl  
000007FE95A30097  or          eax,0FFEE4014h  
000007FE95A3009C  call        000007FEF5062400  
000007FE95A300A1  mov         rbx,rax  
000007FE95A300A4  call        000007FEEC977A00  
00320050  push        ebp  
00320051  mov         ebp,esp  
00320053  push        esi  
00320054  mov         ecx,28380Ch  
00320059  call        002720D4  
0032005E  mov         esi,eax  
00320060  call        72EA2578  
00320065  mov         ecx,eax  
00320067  mov         eax,dword ptr [ecx]  
00320069  mov         eax,dword ptr [eax+2Ch]  
0032006C  call        dword ptr [eax+1Ch]