Posted by Pavel Podlipensky on December 11 2:03 AM
Я, как вы знаете, пишу не только статьи в свой блог, но и код. Программный код. Поэтому, меня зачастую интересуют вопросы, которые нормальным людям в голову и не лезут. Суть сегодняшней дилеммы очень простая – хорошо ли генерировать исключительные ситуации из конструктора? Это скорее философский или этический вопрос, нежели сложная техническая задача. И все же. <p> <strong>Конструкторы</strong> не возвращают каких-либо значений, поэтому было бы здорово сгенерировать ошибку, в случае, если объект не может быть создан. И таким образом, оповестить всех что этот объект использовать дальше нельзя. Уже слышу протестующие крики в свой адрес: “…Конструкторы предназначены для простых операций типа инициализации объекта…” или “…Лучше после попытки создания объекта проверить его на null…”. </p> <p> А я не согласен с этим! </p> <p> Когда мы передаем в конструктор некие параметры, мы обязаны проверить их на валидность. А как вы сообщите об “испорченном” параметре? С помощью null? Что? Опять протесты? </p> <p> “…А давайте оставим конструктор пустым и добавим метод Initialize, который и вернет нам необходимый код состояния инициализации объекта…” </p> <p> Хм, а конструкторы тогда зачем? Для тех, кто все еще сомневается в моих доводах, советую прочесть презентацию <a rel="nofollow" href="http://www.research.att.com/%7Ebs/">Bjarne Stroustrupsa</a> (он настолько крутой, что придумал С++) об <a href="http://www.cise.ufl.edu/%7Emanuel/stroustrup/ex.pdf">“Standard-Library Exception Safety”</a>. И там, все вышесказанное, размазано по 36 страницам. Поэтому генерировать <strong>исключительные ситуации</strong> в конструкторе – это <strong>нормально</strong> (особенно, если вы исповедуете <a href="http://en.wikipedia.org/wiki/Resource_acquisition_is_initialization">RAII</a>). </p> <p> В C#.NET есть еще одна приятная особенность – finalizer вызовится даже в случае ошибки в конструкторе и ресурсы будут освобождены корректно. Кстати и в самом .NET Framework многие базовые классы генерируют исключительные ситуации из конструктора, например Guid, DateTime, Queue, FileStream и другие. </p> <p> А вы генерируете ошибки в конструкторах? </p>
Я, как вы знаете, пишу не только статьи в свой блог, но и код. Программный код. Поэтому, меня зачастую интересуют вопросы, которые нормальным людям в голову и не лезут. Суть сегодняшней дилеммы очень простая – хорошо ли генерировать исключительные ситуации из конструктора? Это скорее философский или этический вопрос, нежели сложная техническая задача. И все же.

Конструкторы не возвращают каких-либо значений, поэтому было бы здорово сгенерировать ошибку, в случае, если объект не может быть создан. И таким образом, оповестить всех что этот объект использовать дальше нельзя. Уже слышу протестующие крики в свой адрес: “…Конструкторы предназначены для простых операций типа инициализации объекта…” или “…Лучше после попытки создания объекта проверить его на null…”.

А я не согласен с этим!

Когда мы передаем в конструктор некие параметры, мы обязаны проверить их на валидность. А как вы сообщите об “испорченном” параметре? С помощью null? Что? Опять протесты?

“…А давайте оставим конструктор пустым и добавим метод Initialize, который и вернет нам необходимый код состояния инициализации объекта…”

Хм, а конструкторы тогда зачем? Для тех, кто все еще сомневается в моих доводах, советую прочесть презентацию Bjarne Stroustrupsa (он настолько крутой, что придумал С++) об “Standard-Library Exception Safety”. И там, все вышесказанное, размазано по 36 страницам. Поэтому генерировать исключительные ситуации в конструкторе – это нормально (особенно, если вы исповедуете RAII).

В C#.NET есть еще одна приятная особенность – finalizer вызовится даже в случае ошибки в конструкторе и ресурсы будут освобождены корректно. Кстати и в самом .NET Framework многие базовые классы генерируют исключительные ситуации из конструктора, например Guid, DateTime, Queue, FileStream и другие.

А вы генерируете ошибки в конструкторах?

blog comments powered by Disqus