цель конструктора по умолчанию - PullRequest
0 голосов
/ 22 мая 2019

Я новичок в C #, просто вопрос о конструкторе по умолчанию. Я читал книгу, в которой написано

конструктор по умолчанию гарантирует, что для всех данных поля класса установлено соответствующее значение по умолчанию

Допустим, у нас есть следующий класс:

class Employee
{
   public string name;
   public int empID;
   public Employee(string name) {
      this.name = name;
   }
}
...
static void Main(string[] args){
   Employee emp = new Employee("Michael");
   Console.WriteLine(emp.empID);
}

и вывод равен 0, что означает, что empID был инициализирован по умолчанию. Но я не инициализировал empID в конструкторе, и при этом у меня нет конструктора по умолчанию (переопределение данным конструктором), так почему empID все еще инициализируется?

быстрое обновление :

для тех, кто сказал, что это не скомпилируется, потому что я изначально скопировал не то, оно должно работать сейчас

enter image description here

Опять же, мой вопрос: почему в учебнике сказано, что конструктор по умолчанию гарантирует , что для всех данных поля класса установлено соответствующее значение по умолчанию , но в моем случае есть не задействован конструктор по умолчанию в то время как empID все еще получает значение по умолчанию?

Ответы [ 3 ]

1 голос
/ 22 мая 2019

Документация для конструкторов C # на самом деле немного плохо сформулирована. Там написано:

Если класс не имеет конструктора, конструктор без параметров генерируется автоматически. и значения по умолчанию используются для инициализации полей объекта. Например, int инициализируется как 0.

" и " здесь, кажется, указывают, что это происходит только в том случае, если вы не предоставляете конструктор, а затем ... что происходит? ... если вы предоставите конструктор?

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


На самом деле не конструктор (-ы) инициализируют поля по умолчанию, т.е. 0 для числовых полей, null для ссылок и т. Д.

Это делается оператором new, до задействования конструкторов .

Если у вас есть этот класс:

public class Test
{
    public int Field;
}

Тогда никакой конструктор не будет специально хранить что-либо в поле Field, оно будет инициализировано равным 0, когда память будет выделена для экземпляра.

Если вместо этого у вас есть этот конструктор:

public Test()
{
    Field = 42;
}

или у вас есть это объявление поля:

public int Field = 42;

(что составляет одно и то же)

Тогда, когда вы создаете экземпляр этого типа, происходит выделение памяти, и значение 0 , что установит начальное значение для Field в 0, а затем конструктор будет вызвано, что установит поле в 42.

1 голос
/ 22 мая 2019

Во-первых, это не скомпилируется, потому что вы не определили конструктор по умолчанию - когда вы определяете конструктор с параметрами, он по умолчанию становится недоступным, если вы не укажете его явно. Так что вам нужно использовать new Employee("some name");

Во-вторых, empID имеет значение по умолчанию 0, поэтому ожидается, что после использования стандартного construcotr (который, как я уже говорил, недоступно), оно имеет значение 0.

Обычно значения по умолчанию для типов значений равны 0 (когда мы говорим о числовых типах, для других типов значений, таких как DateTime, см. Документацию), а для ссылочных типов это null.

0 голосов
/ 22 мая 2019

При инициализации экземпляра класса компилятору необходимо знать пространство, которое ему необходимо выделить для этого экземпляра типа в памяти, и то же самое достигается путем вычисления пространства переменных экземпляра или поля члена данных, а затем экземпляра типа конструктор вызывается для установки начального состояния объекта.

При создании объекта ссылочного типа память, выделенная для объекта, всегда обнуляется до вызова конструктора экземпляра типа. Любые поля, которые конструктор не перезаписывает явно, гарантированно будут иметь значение 0 или ноль.

Ниже приведен пример класса, который я создал без конструктора по умолчанию или без параметров.

public class PersonWithoutDefault
{       
    private string name;      
    public PersonWithoutDefault(string name)
    {
        this.name = name;
    }
}

А на рисунке ниже показан дизассемблированный код с использованием ildasm. Нет конструктора по умолчанию или без параметров.

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...