无参数构造函数的第一个参数是什么?
What is the first argument in a parameterless constructor?
我有这样一个简单的程序:
public class Foo
{
public Foo()
{
}
public int MyInt { get; set; } = 10;
public List<int> MyList { get; set; } = new List<int>();
}
public class Program
{
static public void Main()
{
Console.WriteLine(new Foo().MyInt);
Console.ReadLine();
}
}
我决定看看这个程序的CIL代码(我对Foo的构造函数很感兴趣)。在这里:
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 26 (0x1a)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.s 10
IL_0003: stfld int32 Foo::'<MyInt>k__BackingField'
IL_0008: ldarg.0
IL_0009: newobj instance void class [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()
IL_000e: stfld class [mscorlib]System.Collections.Generic.List`1<int32> Foo::'<MyList>k__BackingField'
IL_0013: ldarg.0
IL_0014: call instance void [mscorlib]System.Object::.ctor()
IL_0019: ret
} // end of method Foo::.ctor
我想知道,当我看到第二行时,ldarg.0
是什么意思? this
指针?但是对象还没有创建。我怎样才能修改它的成员?我的假设是,在调用构造函数之前,clr
首先为对象分配内存。然后将成员初始化为默认值,然后调用构造函数。对象调用是最后一个有趣的时刻。我以为它会是第一个。
虽然对象在构造函数调用之前不是严格意义上的'created',但必须为其分配一些内存。我不知道细节,但我猜想 class 的所有实例方法都有一个隐式的第一个参数,即 this
;对于构造函数也是如此,因为它需要像任何其他实例方法一样引用对象实例。
字段初始值设定项是 C# 功能,而不是 CLR 功能。当您编写字段初始值设定项时,C# 编译器必须将实现该代码的代码放在 某处 ,并且它所放置的位置位于任何构造函数的主体内。
并且由于这些初始值设定项是 运行 "before" 构造函数,这就是为什么实际的 base-class 构造函数是 运行 之后的原因。
(所以,是的,第一个参数就是你推断的,this
)
http://www.philosophicalgeek.com/2014/09/29/digging-into-net-object-allocation-fundamentals/
根据上面的文章,CLR 在调用构造函数之前首先分配内存,这与 C++ 中对象构造的方式相同。
我有这样一个简单的程序:
public class Foo
{
public Foo()
{
}
public int MyInt { get; set; } = 10;
public List<int> MyList { get; set; } = new List<int>();
}
public class Program
{
static public void Main()
{
Console.WriteLine(new Foo().MyInt);
Console.ReadLine();
}
}
我决定看看这个程序的CIL代码(我对Foo的构造函数很感兴趣)。在这里:
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 26 (0x1a)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.s 10
IL_0003: stfld int32 Foo::'<MyInt>k__BackingField'
IL_0008: ldarg.0
IL_0009: newobj instance void class [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()
IL_000e: stfld class [mscorlib]System.Collections.Generic.List`1<int32> Foo::'<MyList>k__BackingField'
IL_0013: ldarg.0
IL_0014: call instance void [mscorlib]System.Object::.ctor()
IL_0019: ret
} // end of method Foo::.ctor
我想知道,当我看到第二行时,ldarg.0
是什么意思? this
指针?但是对象还没有创建。我怎样才能修改它的成员?我的假设是,在调用构造函数之前,clr
首先为对象分配内存。然后将成员初始化为默认值,然后调用构造函数。对象调用是最后一个有趣的时刻。我以为它会是第一个。
虽然对象在构造函数调用之前不是严格意义上的'created',但必须为其分配一些内存。我不知道细节,但我猜想 class 的所有实例方法都有一个隐式的第一个参数,即 this
;对于构造函数也是如此,因为它需要像任何其他实例方法一样引用对象实例。
字段初始值设定项是 C# 功能,而不是 CLR 功能。当您编写字段初始值设定项时,C# 编译器必须将实现该代码的代码放在 某处 ,并且它所放置的位置位于任何构造函数的主体内。
并且由于这些初始值设定项是 运行 "before" 构造函数,这就是为什么实际的 base-class 构造函数是 运行 之后的原因。
(所以,是的,第一个参数就是你推断的,this
)
http://www.philosophicalgeek.com/2014/09/29/digging-into-net-object-allocation-fundamentals/
根据上面的文章,CLR 在调用构造函数之前首先分配内存,这与 C++ 中对象构造的方式相同。