Каков предпочтительный способ построения объектов в C #? Параметры конструктора или свойства?

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

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

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

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

27
задан Peterdk 14 May 2009 в 12:29
поделиться

10 ответов

Предпочтительный способ зависит от вашего дизайна.

Свойства конструктора предназначены для элементов, которые требуются вашему объекту для правильного построения. Другими словами, любые свойства, которые объект должен иметь для инициализации, должны находиться в конструкторе (обычно вам не нужен частично инициализированный объект после вызова конструктора, если только вы не создаете шаблон фабрики или построителя и конструктор скрыт от всех, кроме фабрики / построителя).

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

Например, , у вас может быть объект, представляющий человека. Человеку нужно инициализировать имя и возраст, но адрес, по которому они живут, является необязательной конфигурацией. Итак, имя и возраст являются параметрами конструктора, а адрес - свойством чтения / записи.

Person johnDoe = new Person("John Doe", 24) { Address = "42 Adams Street" };
40
ответ дан 28 November 2019 в 04:30
поделиться

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

0
ответ дан 28 November 2019 в 04:30
поделиться

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

0
ответ дан 28 November 2019 в 04:30
поделиться

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

Однако для неизменяемых типов подход конструктора - единственный разумный вариант. Интересно (возможно), что именованные / необязательные параметры в C # 4.0 позволяют нечто подобное инициализаторам объектов для неизменяемых типов - см. Здесь .

Подход конструктора также очень популярен для фреймворков инверсии управления, поскольку он явно рекламирует то, что этому классу нужно для функционирования.

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

12
ответ дан 28 November 2019 в 04:30
поделиться

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

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

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

7
ответ дан 28 November 2019 в 04:30
поделиться

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

5
ответ дан 28 November 2019 в 04:30
поделиться

Несколько мыслей:

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

  2. Если вы отметите IL, вы обнаружите, что инициализатор объекта не является «атомарным». Если вы напишете такой код (я не рекомендую, а просто пример):

     using (p = New Person () {Name = GetName (), Age = GetAge ()})
    {
     // бла, бла
    }
    

    Если есть исключение в GetAge () , вы создадите экземпляр Person в поврежденном состоянии. Хуже того, вы никогда не сможете войти в область using, и этот экземпляр не будет удален, как вы могли себе представить.

4
ответ дан 28 November 2019 в 04:30
поделиться

Второй способ - это просто синтаксический сахар для установки свойств вручную:

Person p = new Person();
p.Name = "name";
p.Age = 24;

Вы также не зависите от конструктора, который может не инициализировать все свойства, которые вы хотите установить.

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

2
ответ дан 28 November 2019 в 04:30
поделиться

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

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

Я бы использовал инициализаторы объектов только для типов, которые не требуют создания каких-либо свойств. Отсюда конструктор по умолчанию.

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

Но я не думаю, что есть большой смысл в том, что вы можете создать Person без имени.

2
ответ дан 28 November 2019 в 04:30
поделиться

Мои основные соображения по этому вопросу: 1) Сколько данных будет иметь объект, создающий экземпляр, при создании экземпляра объекта и 2) Насколько инкапсулированным должен быть класс? Если после установки свойства не должны иметь возможность изменяться (по крайней мере, из-за каких-либо внешних сущностей), я бы использовал конструктор, поскольку конструктор может устанавливать любые свойства только для чтения, а также любые свойства для чтения / записи.

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

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

0
ответ дан 28 November 2019 в 04:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: