2009-12-10 3 views
2

Я хочу изящно обрабатывать конкретное исключение с определенным сообщением. К сожалению, это просто исключение ArgumentException, а не то, что я ищу. В этом случае сообщение «Элемент с тем же ключом уже добавлен». Это исключительный случай, но я хочу обработать его, чтобы я мог либо превратить его в конкретное исключение, либо проинформировать пользователя с нетехнической терминологией.Можно ли получить исключение на основе сообщения?

Кажется, что плохая идея закодировать его для поиска этого сообщения, но что еще я могу сделать?

+3

Является ли это исключение брошенным вами или компонентом, которым вы не контролируете? –

+0

Я собирался задать тот же вопрос. ваш вопрос звучит так, как исключение выбрасывается сторонним компонентом. –

+0

Он забрасывается в методе ToDictionary. Я мог бы проверить наличие дубликатов в источнике, но это исключение, а не нормальное обстоятельство. –

ответ

4

Вы тот, кто добавляет товар? Если да, напишите код, чтобы избежать его в первую очередь.

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

EDIT: Вместо того, чтобы звонить ToDictionary, позвоните по телефону ToLookup. Затем вы можете проверить любые результаты, которые содержат несколько записей.

В качестве альтернативы, напишите свою собственную версию ToDictionary, которая обрабатывает это правильно для вашей ситуации - это довольно просто.

+0

Я выполняю запрос, а затем использую расширение ToDictionary. Верно, что я мог проверить результаты запроса, но это дополнительный код и время обработки для чего-то, что является исключением из правила, и обычно этого не должно происходить. –

+0

не полностью. запустите расширение AssertUnique на результат запроса, затем ToDictionary. вам нужно будет авторизовать расширение, но оно будет выглядеть как 'IDictionary results = query.AssertUniqueKeys() .ToDictionary()' –

+0

Я понимаю, что вы говорите, и это, вероятно, маршрут, который я возьму, но вы должен признать, что это не так. Кроме того, я столкнулся с другой ситуацией, когда это было исключение SqlException, и я не мог использовать этот вид «взлома». –

2

Вы можете создать собственное исключение, которое происходит из класса Exception.

Например:

public class KeyExistsException : Exception 
{ 
    // ... 
} 

Однако, если это исключение из компонента третьей стороны, есть мало что можно сделать, чем проверки для сообщения, кроме метода ContainsKey. ArgumentException не имеет ничего, кроме String, чтобы предоставить информацию о том, что это значит.

0

Я согласен, что это пахнет, но, похоже, у вас нет выбора ...

2

Никогда не используйте Message свойство для чего-нибудь, кроме отображения на человека. Что делать, если им нужно изменить пунктуацию на сообщение, или, не дай Бог, изменить написание или формулировку?

+0

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

1

Вы можете избежать исключения и проверить словарь с помощью метода .ContainsKey перед добавлением новых записей.

+0

Я запускаю запрос, а затем использую расширение ToDictionary. Верно, что я мог проверить результаты запроса, но это дополнительный код и время обработки для чего-то, что является исключением из правила, и обычно этого не должно происходить. –

1

Я сделал это раньше, и молния не ударила меня. Все же.

+0

Кто осмелился это сделать? – Joshua

0

Возможно, вам придется сделать это таким образом. Но я бы действительно предложил подумать о вашем дизайне. Это похоже на симптом сомнительного дизайна.

try { 
    // your code 
} 
catch (ArgumentException ex) { 
    if (ex.Message != "An item with the same key has already been added") throw; 

    // handle your case 
} 
+0

Что произойдет, если используется другая строка сообщений? В 'ArgumentException' нет ничего, что диктует значение свойства Message. Это деталь реализации, которая может быть изменена в любое время. –

+0

Согласен. Я бы не использовал этот подход. – recursive

+0

Да, это именно та дилемма, о которой я говорю. :-) –

2

Если вы создаете словарь, используя метод Enumerable.ToDictionary, затем ArgumentException всегда означает дубликат ключа. Вам вообще не нужно проверять сообщение, просто поместите вызов ToDictionary в свой собственный оператор и поймайте ArgumentException.

Об этом говорится в Перечисленном .ToDictionary documentation.

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

+0

Хм, изначально это выглядит идеально, но я полагаю, это может измениться так же легко, как и сообщение. –

+0

Нет необходимости ждать, пока Enumerable.ToDictionary выбросит исключение - невероятно просто написать собственную версию, которая делает то, что вы хотите. Не забывайте, что если источник данных как-то некорректен (или функция сопоставления), который все еще может вызывать ArgumentNullException, так что вы можете в конечном итоге скрывать неприятную ошибку. –

+0

ArgumentException с меньшей вероятностью изменится, чем само сообщение, поскольку оно фактически документировано (и не изменило смысл версии 2 .NET Framework). Выделение «безопасной» версии с вызовами ContainsKey является одним из вариантов, но не будет выполнено, если в большинстве случаев дубликатов нет. – Aaronaught

0

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

1

Другая причина, по которой не фильтровать исключения на основе сообщения, заключается в том, что сообщение может быть локализовано! Это особенно справедливо для исключений, создаваемых компонентами .NET framework.

Смежные вопросы