C # конструкторы - PullRequest
       26

C # конструкторы

12 голосов
/ 30 марта 2011

Может ли кто-нибудь посоветовать мне, какой подход использовать при написании C# конструкторов?

В других языках, например C++, все в порядке - вы обычно не делаете внутренние поля видимыми и не предоставляетеgetters / setters для них.

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


C#, однако, имеет properties, что позволяет нам писать что-то вроде:

Class x = new Class { Field1 = new Field1 ...., Field2 = new Field2 }

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

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

Теперь - можно ли удалять избыточные конструкторы и разрешать создание объектов с помощью инициализации поля?

Каковы недостатки этого подхода?ч?Может ли кто-нибудь дать общие рекомендации о комбинировании использования полей и конструкторов, некоторые rules of thumb, вероятно?

Спасибо.

Ответы [ 9 ]

16 голосов
/ 30 марта 2011

Мое эмпирическое правило простое: если что-то требуется для полного конструирования объекта, это должен быть параметр ctor.

Хорошим примером является один из вспомогательных объектов Stream, таких как StreamReader или BinaryReader.Они не могут функционировать без связанного объекта Stream, поэтому это должно быть указано в конструкторе.

6 голосов
/ 30 марта 2011

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

4 голосов
/ 30 марта 2011

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

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

Однако вопрос в чем-то вроде ложной дихотомии.C ++ ведет себя так же, как C # - «Поля» (которые на самом деле являются свойствами - поля являются переменными уровня класса) обычно используются в качестве методов получения / установки для установки внутренних значений, а синтаксис new, который позволяет устанавливать поля, простостенография для

Class x = new Class();
x.Field1 = new Field1();
x.Field2 = new Field2();
2 голосов
/ 30 марта 2011

Код, который вы разместили, использует так называемые Object Initializer, которые на самом деле являются просто синтаксическим сахаром, который был представлен довольно недавно. Использование инициализаторов объектов - это просто краткий способ вызова конструкторов и , устанавливающих свойства. Вы должны продолжать использовать конструкторы в C # так же, как вы использовали их в других языках - общее правило состоит в том, что если для класса требуется объект или значение для его правильной инициализации, этот параметр должен пройти через конструктор. Если значение не требуется, целесообразно сделать его устанавливаемым свойством.

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

2 голосов
/ 30 марта 2011

Рекомендуется создавать объект в работоспособном состоянии; попытаться ограничить зависимость от установщиков свойств.

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

1 голос
/ 30 марта 2011

Синтаксис инициализатора объекта - это просто синтаксический сахар.Даже в C # 1 вы могли бы написать

Class c = new Class();
c.Property1 = value1;
c.Property2 = value2;
c.Property3 = value3;
....

C # 3 в основном сокращает синтаксис до:

Class c = new Class 
{
   Property1 = value1, 
   Property2 = value2, 
   Property3 = value3
   ....
}

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

1 голос
/ 30 марта 2011

Подход открытого конструирования без параметров с последующей инициализацией свойства популярен (требуется?) Для использования в XAML, многие игрушки WPF делают это.

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

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

0 голосов
/ 30 марта 2011

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

0 голосов
/ 30 марта 2011

Это нормально?Ну, это зависит ...

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...