Почему членские переменные должны быть инициализированы в конструкторах?

В Postgres вы можете использовать LEFT JOIN в выражении UPDATE со следующим синтаксисом:

UPDATE a 
SET a.is_active = CASE WHEN b.id IS NULL THEN FALSE ELSE TRUE
FROM TABLE_A a
LEFT JOIN TABLE_B b ON a.id = b.id
5
задан Pops 28 June 2011 в 20:29
поделиться

6 ответов

  • Если у Вас есть несколько конструкторов, Вы могли бы хотеть инициализировать поле к различным значениям

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

14
ответ дан 18 December 2019 в 06:04
поделиться

Одна причина сделать это состоит в том, что это помещает весь код инициализации в одном месте, которое удобно для других, читающих Ваш класс. Сказав это я действительно не делаю этого по двум основным причинам. (1) я использую TDD/поблочное тестирование для определения поведения моего класса. Если Вы хотите знать то, что делает конструктор без параметров, необходимо действительно считать тесты, я основывался на конструкторе без параметров. (2) С C# 3.0 я обычно использую автоматические свойства и встраиваю инициализацию с конструктором без параметров для инстанцирования объекта. Это намного более гибко, и это исправляет определение свойств в строке, где код используется. Это переопределило бы любую инициализацию в конструкторе, таким образом, я редко помещал любого там. Конечно, это только относится к C#.

Напр. (2)

  var foo = new Foo { Bar = "baz" };

  public class Foo
  {
       public string Bar { get; set; }

       public Foo() { }
  }
2
ответ дан 18 December 2019 в 06:04
поделиться

Компилятор C# возьмет любую нестатическую членскую инициализацию, что Вы действительно встраиваете и перемещаете его в конструктора для Вас. Другими словами, это:

class Test
{
    Object o = new Object();
}

компилируется в это:

class Test
{
    Object o;

    public Test()
    {
        this.o = new Object();
    }
}

Я не уверен, как компиляторы для других языков обрабатывают это, но, что касается C#, что это - вопрос стиля, и Вы свободны сделать, какой бы ни Вы желаете. Обратите внимание на то, что статические поля обрабатываются по-другому: прочитайте эту статью для получения дополнительной информации об этом.

10
ответ дан 18 December 2019 в 06:04
поделиться

иногда у конструктора есть параметры, которые используются для инициализации внутренних переменных. Например, размер массивов

1
ответ дан 18 December 2019 в 06:04
поделиться

Мне всегда нравится думать о классе как о фабрике для объектов и конструкторе как заключительная остановка на производственной линии. Поля, объявленные в классе, являются проектами, описывающими объект, но проект не будет понят в объект, прежде чем такой объект будет заказан через вызов конструктору... Кроме того, как кто-то указал, делание всех Ваших инициализаций в Вашем конструкторе улучшит удобочитаемость, а также это, wil предусматривают dynamicity в инициализации (это не мог бы быть конструктор без параметров, Вы имеете дело с).

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

0
ответ дан 18 December 2019 в 06:04
поделиться

Я не услышал неопровержимого довода для не предложения обеих опций. Я подозреваю, что настоящая причина имеет отношение к упрощению структуры языка с точки зрения парсинга. Это особенно верно на языках C-производной, где парсинг оператора присваивания требует 75% правил синтаксиса языка. Мне кажется, что, позволяя это и определение, как это работало бы точно, будет хорошо. Я соглашаюсь с комментарием Michael об увеличении сложности, поскольку Вы вставляете наследование и несколько конструкторов, но просто потому что Вы добавляете опцию, не означает, что необходимо использовать его. Я голосовал бы для поддержки обоих даже при том, что мой голос действительно не составляет в целом много.

0
ответ дан 18 December 2019 в 06:04
поделиться