.Net Бросать исключения из ToString? - PullRequest
6 голосов
/ 03 августа 2010

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

Спасибо.

Ответы [ 7 ]

8 голосов
/ 03 августа 2010

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

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

6 голосов
/ 03 августа 2010

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

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

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

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

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

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

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

2 голосов
/ 03 августа 2010

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

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

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

0 голосов
/ 03 августа 2010

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

0 голосов
/ 03 августа 2010

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

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

0 голосов
/ 03 августа 2010

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

0 голосов
/ 03 августа 2010

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

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

...