В справочном источнике для объекта это код для конструктора:
// Creates a new instance of an Object.
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[System.Runtime.Versioning.NonVersionable]
public Object()
{
}
Там ничего не происходит.
В комментариях вы спрашиваете, какчлены класса инициализируются к их значению по умолчанию.Метод Main()
в следующей программе ...
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Program program = new Program();
}
}
}
переводится компилятором в следующий MSIL:
IL_0000: nop
IL_0001: newobj instance void ConsoleApp1.Program::.ctor()
IL_0006: stloc.0
IL_0007: ret
Интересная инструкция здесь newobj .Что среди прочего:
выделяет новый экземпляр класса, связанный с ctor, и инициализирует все поля в новом экземпляре как 0 (соответствующего типа) или нулевые ссылки в зависимости от ситуации.
Итак, newobj инициализирует всех членов класса для некоторого типа 0
или null
.
В комментариях вы спрашиваете, что произойдет, если вы инициализируете поле дляконкретное значение.Если мы изменим программу выше:
namespace ConsoleApp1
{
class Program
{
private int i = 1;
public Program()
{
i = 2;
}
static void Main(string[] args)
{
Program program = new Program();
}
}
}
Мы добавили поле i
, которое инициализируется в 1
, и конструктор, который устанавливает i
в 2
.
MSIL для конструктора класса Program
выглядит следующим образом:
IL_0000: ldarg.0
IL_0001: ldc.i4.1
IL_0002: stfld int32 ConsoleApp1.Program::i
IL_0007: ldarg.0
IL_0008: call instance void [mscorlib]System.Object::.ctor()
IL_000d: nop
IL_000e: nop
IL_000f: ldarg.0
IL_0010: ldc.i4.2
IL_0011: stfld int32 ConsoleApp1.Program::i
IL_0016: ret
Итак,
- newobj создает объект и инициализирует его память(установка
i
в 0
). - Конструктор
Program
запускается и ldc.i4.1
, а затем stfld ... i
устанавливает i
в 1
. - Затемвызывается конструктор базового класса
System.Object
. - А затем (все еще в конструкторе
Program
) i
устанавливается в 2
(ldc.i4.2
, за которым следует stfld ... i
).
Таким образом, i
устанавливается 3 раза (на 0, 1 и 2), и когда конструктор базового класса запускается, i
имеет другое значение, чем когда конструктор Program
отделка.
Порядок, в котором запускаются инициализаторы и конструкторы, см. эти записей Эрика Липперта.