Я, как вы знаете, пишу не только статьи в свой блог, но и код. Программный код. Поэтому, меня зачастую интересуют вопросы, которые нормальным людям в голову и не лезут. Суть сегодняшней дилеммы очень простая – хорошо ли генерировать исключительные ситуации из конструктора? Это скорее философский или этический вопрос, нежели сложная техническая задача. И все же.
Конструкторы не возвращают каких-либо значений, поэтому было бы здорово сгенерировать ошибку, в случае, если объект не может быть создан. И таким образом, оповестить всех что этот объект использовать дальше нельзя. Уже слышу протестующие крики в свой адрес: “…Конструкторы предназначены для простых операций типа инициализации объекта…” или “…Лучше после попытки создания объекта проверить его на null…”.
А я не согласен с этим!
Когда мы передаем в конструктор некие параметры, мы обязаны проверить их на валидность. А как вы сообщите об “испорченном” параметре? С помощью null? Что? Опять протесты?
“…А давайте оставим конструктор пустым и добавим метод Initialize, который и вернет нам необходимый код состояния инициализации объекта…”
Хм, а конструкторы тогда зачем? Для тех, кто все еще сомневается в моих доводах, советую прочесть презентацию Bjarne Stroustrupsa (он настолько крутой, что придумал С++) об “Standard-Library Exception Safety”. И там, все вышесказанное, размазано по 36 страницам. Поэтому генерировать исключительные ситуации в конструкторе – это нормально (особенно, если вы исповедуете RAII).
В C#.NET есть еще одна приятная особенность – finalizer вызовится даже в случае ошибки в конструкторе и ресурсы будут освобождены корректно. Кстати и в самом .NET Framework многие базовые классы генерируют исключительные ситуации из конструктора, например Guid, DateTime, Queue, FileStream и другие.
А вы генерируете ошибки в конструкторах?