Должен ли мы всегда включать конструктор по умолчанию в class?

Мне задали этот вопрос коллега, который должен всегда включать конструктор по умолчанию в classе? Если да, то почему? Если нет, почему бы и нет?

пример

public class Foo { Foo() { } Foo(int x, int y) { ... } } 

Я также заинтересован в том, чтобы рассказать об этом от экспертов.

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

 public class Foo { } 

Компилятор будет генерировать это как:

 public class Foo { public Foo() { } } 

Однако, как только вы добавите другой конструктор

 public class Foo { public Foo(int x, int y) { // ... } } 

Компилятор больше не будет автоматически генерировать конструктор по умолчанию для вас. Если class уже использовался в другом коде, который основывался на наличии конструктора по умолчанию, Foo f = new Foo(); , этот код теперь сломается.

Если вы не хотите, чтобы кто-то мог инициализировать class без предоставления данных, вы должны создать конструктор по умолчанию, который является private чтобы быть явным в том, что вы запрещаете создание экземпляров без входных данных.

Однако есть моменты, когда необходимо предоставить конструктор по умолчанию (будь то открытый или закрытый). Как уже упоминалось ранее, для некоторых типов сериализации требуется конструктор по умолчанию. Также существуют случаи, когда class имеет несколько параметризованных конструкторов, но также требует инициализации «нижнего уровня», и в этом случае может использоваться частный конструктор по умолчанию, который привязан от параметризованных конструкторов.

 public class Foo { private Foo() { // do some low level initialization here } public Foo(int x, int y) : this() { // ... } public Foo(int x, int y, int z) : this() { // ... } } 

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

Например, если свойства Foo.X и Foo.Y являются неизменяемыми после построения, конструктор по умолчанию на самом деле не имеет смысла. Даже если бы это использовалось для «пустого» Foo, статический Empty аксессуар был бы более узнаваем.

Я бы сказал, нет , определенно не всегда . Предположим, у вас есть class с некоторыми полями readonly, которые должны быть инициализированы до некоторого значения, и нет разумных значений по умолчанию (или вы не хотите, чтобы они были)? В этом случае я не думаю, что конструктор без параметров имеет смысл.

Наличие конструктора по умолчанию – это только хорошая идея, если имеет смысл иметь такой объект.

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

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

Да. Лучше иметь конструктор по умолчанию, чтобы избежать путаницы. Я видел, как люди ничего не делают внутри конструктора по умолчанию (даже в собственных classах Microsoft), но все равно хотят сохранить его, поскольку объекты автоматически получают значение по умолчанию (тип). Классы, которые не определяют конструктор по умолчанию, .NET автоматически добавят их для вас.

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

В большинстве случаев конструктор по умолчанию – хорошая идея. Но поскольку вы используете слово «всегда», все, что вам нужно, это один контрпример. Если вы посмотрите на Framework, вы найдете много. Например, System.Web.HttpContext.

Общий тип может быть создан только с помощью средств C # (без отражения), если он имеет конструктор по умолчанию. Кроме того, необходимо указать ограничение типа generic new() :

 void Construct() where T : new() { var t = new T(); ... } 

Вызов этого метода с использованием аргумента типа типа, который не имеет конструктора по умолчанию, приводит к ошибке компилятора.

Давайте будем гением компьютера.