Должен ли я использовать инициализатор объекта или конструктор?
Я только что узнал об инициализаторах объектов и мне было интересно, как лучше их использовать.
Вот что я читал о них: http://msdn.microsoft.com/en-us/library/vstudio/bb384062.aspx Ясно, что они необходимы для создания анонимных типов, но я хотел бы знать, должен ли я попробуйте предпочесть их нормальным конструкторам во всех остальных случаях.
4 ответа
В настоящее время я вижу следующие проблемы с их использованием:
- Назначенные свойства должны быть изменяемыми. Это кажется нежелательным, потому что, если данные передаются в конструктор, я могу проверить их там и вызвать сбой при создании объекта, если предоставленные данные недостаточны или неправильны. Если данные могут быть назначены со свойством, мне внезапно придется выяснить, в каком состоянии находится мой объект, правильно ли все еще создано или в каком другом состоянии я могу находиться.
- Назначенные свойства должны быть общедоступными. Это означает, что доступ к вещам, которые в противном случае могут быть закрытыми, должен быть открыт, а затем ограничен с помощью интерфейса или чего-то подобного.
Итак, моя рабочая теория такова: не используйте инициализаторы объектов, они поощряют глупости.
Я хотел бы знать, должен ли я попытаться предпочесть их нормальным конструкторам во всех других случаях.
Я бы сказал нет.
Конструкторы имеют огромное количество преимуществ. Используя конструктор, компилятор обеспечит предоставление всех необходимых данных вашему типу. Это означает, что вы можете сделать невозможным создание экземпляра вашего типа, который находится в недопустимом состоянии, что позволяет вам заранее предотвращать множество ошибок.
С другой стороны, инициализаторы объектов создают много недостатков. Вы должны предоставить общедоступные свойства для любых данных, которые вам нужно инициализировать. Они не требуются во время строительства, поэтому пользователи вашего типа могут случайно пропустить некоторые данные.
В общем, все, что требуется для работы вашего класса, должно требоваться в конструкторе. Инициализаторы объектов все еще можно использовать, даже если у вас есть собственный конструктор, но его следует использовать только для данных, которые необязательны при настройке вашего класса. Смешивание обоих при инициализации - это хорошо, а это значит, что вы можете сделать:
var yourInst = new YourClass(req1, req2) { OptionalProperty = opt1 }
Это может помочь уменьшить количество требуемых перегрузок конструктора (аналогично использованию необязательных аргументов, но без некоторых недостатков управления версиями в необязательных аргументах).
Я верю, что вы путаете вещи.
Инициализаторы объектов будут вызывать конструктор класса по умолчанию (или указанный)! Таким образом, вы не можете использовать инициализаторы объекта вместо обычного конструктора. Поэтому при использовании инициализатора объекта вы все равно вызываете конструктор.
Если вас интересуют инициализаторы объектов для разрабатываемого вами класса, ответ остается в силе. Обязательно предоставьте необходимые конструкторы, которые имеют смысл. Вам не нужно делать ничего особенного, чтобы включить / разрешить инициализаторы объектов. Они являются синтаксическим сахаром, предоставляемым компилятором C# начиная с версии 3.0, и позволяют пользователям вашего класса инициализировать открытых членов вашего класса сразу после создания.
Хорошее эмпирическое правило:
- Если требуется, чтобы класс работал правильно, это должен быть параметр конструктора
- Если его изменение нарушит класс, это должен быть параметр конструктора
- Если он необязательный, имеет нормальное значение по умолчанию и / или просто и безопасно меняет поведение класса, он должен быть инициализатором.
Основным преимуществом инициализаторов является то, что вам не нужно устанавливать их при создании объекта - вы можете установить их позже, основываясь на другой логике.