2015-02-20 1 views
7

Если конструктор по умолчанию, который будет инициализировать переменные-члены к нулю, то, как идут это будет возможноКто будет инициализировать данные? Это конструктор или что-то еще?

class A   
{   
    public int i;   
    public int j;   
    public A()   
    {   
     i=12;   
    }   
}   
class Program   
{   
    static void Main(string[] args)   
    {   
     A a = new A();   
     Console.WriteLine(a.i + "" + a.j);   
     Console.ReadLine();   
    }   
} 
+0

Как получить j будет инициализирован до нуля в указанном выше контексте – sathishhanumandla

+0

, если объявленный конструктор по умолчанию будет выполнен, когда мы объявим его как 'A a = new A();' – sathishhanumandla

ответ

1

Ответ заключается в том, что с # числовые поля 0 по умолчанию. В то время как в C++ поле int является некоторым случайным значением по умолчанию

+2

Пожалуйста, будьте точнее и говорите о * Типы значений * vs * Reference Types * ... –

+0

Хорошая точка :) Я обновлю сообщение позже (в настоящее время на тренировках) – Blaatz0r

19

Поскольку инициализаторы полей запускаются до конструкторов. Вы не присвоили значение j в своем конструкторе, это будет 0 по умолчанию, так как это int.

От 10.4.4 Field initialization

Начальное значение поля, будь то статическое поле или поле экземпляра, значение по умолчанию (Section 5.2) из типа месторождения.

Кто это? Ну, похоже, newobj делает это, когда вы звоните new. Посмотрите dyatchenkos' answer для более подробной информации.

+2

@Downvoter позаботится прокомментировать, по крайней мере, чтобы я мог видеть, где я могу ошибаться? –

+6

Я думаю, что OP _already_ знает это и спрашивает, где происходит эта инициализация. –

+0

@ Selman22 Что значит «где»? C# скомпилирован в код MSIL, а затем после компиляции он будет выглядеть как 'public int j = 0;' – dyatchenko

1

Во время создания экземпляра его переменные также доступны. И поскольку int не имеет значения NULL, он инициализирует по умолчанию (int). Который является 0

1

C# set default int to 0. Подробнее о значения по умолчанию найдены here

И еще более, так как они являются полями это apply

Начальное значение поля, будь то статическое поле или поле экземпляра, это значение по умолчанию.

Конструктор по умолчанию присвоит i к 12 но j будет 0 как значение default, так как он не был назначен в любом месте в конструкторе.

11

Инициализация поля происходит до вызова конструктора через команду newobj. Это легко проверить, после декомпиляции исполняемого файла со следующим C# код:

using System; 
namespace ConsoleApplication1 
{ 
    public class A { public int j; } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      A g = new A(); 
      Console.WriteLine(g.j); 
     } 
    } 
} 

Часть decompilted кода MSIL (метод основной):

//000017:   { 
    IL_0000: nop 
//000018:    A g = new A(); 
    IL_0001: newobj  instance void ConsoleApplication1.A::.ctor() 
    IL_0006: stloc.0 
//000019:    Console.WriteLine(g.j); 
    IL_0007: ldloc.0 
    IL_0008: ldfld  int32 ConsoleApplication1.A::j 
    IL_000d: call  void [mscorlib]System.Console::WriteLine(int32) 
    IL_0012: nop 
//000020:   } 

Как мы можем видеть MSIL использует newobj инструкции для создания экземпляра класса A. Согласно следующему microsoft acticle:

Инструкция newobj выделяет новый экземпляр класса, связанного с CTOR и инициализирует все поля в новом экземпляре до 0 (от соответствующего типа) или нулевые ссылки как подходящее. Затем он вызывает конструктор с указанными аргументами вместе с вновь созданным экземпляром .После вызова конструктора теперь инициализированная ссылка на объект (тип O) помещается в стек.

Если это неверно, прокомментируйте, иначе назначьте его как правильный ответ, пожалуйста.

+1

Я думаю, что память фактически обнулена задолго до того, как вызывается инструкция 'newobj'. 'newobj' всегда захватывает следующий неиспользуемый кусок кучи gen0, и тривиально гарантировать, что неиспользуемые разделы кучи gen0 всегда обнуляются (память обнуляется, когда она поступает из ОС, и ее можно снова обнулить, когда сбор мусора пропуск происходит, и уплотнение превращает используемую память обратно в неиспользованный) –

2

В переменных C#, int значения по умолчанию всегда будут равными 0, если не указано иное. В конструкторе:

public A() 
{ 
    i=12; 
} 

Когда объект конкретизируется, ваша собственность i будет инициализирована до 12, в то время как ваша собственность j будет инициализирована в 0.

В коде:

public class Program 
{ 
    A a = new A(); // You instantiated your object, i will be assigned 12 
    Console.WriteLine(a.i.ToString() + "" + a.j.ToString()); 
    // Your output will be 12 0 because you didn't initialize j so the default is 0 
    Console.ReadLine(); 
} 

Надеюсь, это поможет!

+0

Я боюсь, что это еще одно сердце. – dyatchenko

Смежные вопросы