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


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

пример

public class Foo {

    Foo() { }

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

}

мне также интересно получить некоторые сведения об этом от экспертов.

8 61

8 ответов:

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

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()
   {
      // ...
   }
}

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

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

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

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

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

в качестве примечания, при использовании структуры вместо класса, обратите внимание, что есть ни

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

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

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

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

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

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