.Net Throwing exceptions от ToString?

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

Какие-либо мысли?

Код: http://pastebin.com/mLEkBAAz

Спасибо.

6
задан TehOne 2 August 2010 в 23:54
поделиться

7 ответов

Я бы не стал этого делать. Я не вижу ситуации, в которой было бы лучше, чтобы метод ToString() выбрасывал исключение вместо того, чтобы, например, вернуть представление строки Object.ToString().

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

Edit:

Итак, судя по тому, что вы нам говорите, я, вероятно, не стал бы помещать код, который вы помещаете в .ToString(). Я бы нашел другое название метода, скажем, .GetXMLRepresentation(), а также .CheckIfIsInValidState(). Затем я бы заставил .GetXMLRepresentation() выбрасывать исключение, если вы попытаетесь вызвать его в недопустимом состоянии. Но я бы хотел использовать .ToString() для других целей.

8
ответ дан 8 December 2019 в 14:39
поделиться

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

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

И поскольку ваша перегрузка ToString () предположительно не принимает никаких аргументов, вызывающая сторона никогда не должна вызывать исключение по вине.

Поэтому нет, я не могу придумать никаких исключений, которые выдала бы ToString ().

Правка : В случае кода pastebin лучший способ сделать это - объединить параметры запроса в отдельный класс - назовите его SearchParameters или что-то в этом роде.

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

Таким образом, если в вашем объекте SearchQuery когда-либо будет больше методов, которые полагаются на наличие действительного поискового запроса, вам не нужно будет повторять код проверки, и, конечно же, ToString () никогда не вызовет исключения.

6
ответ дан 8 December 2019 в 14:39
поделиться

Жандармерия (инструмент статического анализа) имеет правило «Не бросать в неожиданное местоположение» , которое гласит:

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

Вряд ли официальный Microsoft, но это очень хороший показатель того, что использование метода ToString было бы плохой практикой.

2
ответ дан 8 December 2019 в 14:39
поделиться

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

0
ответ дан 8 December 2019 в 14:39
поделиться

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

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

0
ответ дан 8 December 2019 в 14:39
поделиться

Исключения являются частью контракта метода object ToString и, как таковые, любые исключения, выбрасываемые реализациями производных классов, по моему мнению, не должны отличаться от исключений, выбрасываемых реализацией базового класса. Я не думаю, что ToString вызывает какое-либо исключение в любом из базовых классов BCL от Microsoft, поэтому я бы придерживался этого соглашения.

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

0
ответ дан 8 December 2019 в 14:39
поделиться

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

0
ответ дан 8 December 2019 в 14:39
поделиться
Другие вопросы по тегам:

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