Должны ли мы всегда включать конструктор по умолчанию в класс? - PullRequest
65 голосов
/ 11 сентября 2010

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

* ** 1003 тысяча два * Пример
public class Foo {

    Foo() { }

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

}

Мне также интересно узнать об этом у экспертов.

Ответы [ 8 ]

108 голосов
/ 11 сентября 2010

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

public class Foo
{ 
} 

Компилятор сгенерирует это как:

public class Foo
{ 
    public Foo() { }  
} 

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

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

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

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

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

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()
   {
      // ...
   }
}
19 голосов
/ 11 сентября 2010

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

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

12 голосов
/ 11 сентября 2010

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

5 голосов
/ 12 сентября 2010

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

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

1 голос
/ 12 сентября 2010

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

1 голос
/ 12 сентября 2010

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

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

0 голосов
/ 10 марта 2016

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

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

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

0 голосов
/ 11 сентября 2010

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

...