2009-01-06 3 views
47

Зачем нам создавать пользовательские исключения в .NET?Зачем создавать пользовательские исключения?

+0

В качестве помощи, возможно повторное открытие на этот вопрос, из [Как создать пользовательские исключения] (https://msdn.microsoft.com/ en-us/library/87cdya3t% 28v = vs.110% 29.aspx) в MSDN: * «Если вы хотите, чтобы пользователи могли программно различать некоторые условия ошибки, вы можете создавать свои собственные пользовательские исключения». * – DavidRR

ответ

48

Конкретных таможенных исключения позволяют разделять различные типы ошибок для утверждений об улове.Общая конструкция для обработки исключений заключается в следующем:

try 
{} 
catch (Exception ex) 
{} 

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

try 
{} 
catch (CustomException1 ex1) 
{ 
    //handle CustomException1 type errors here 
} 
catch (CustomException2 ex2) 
{ 
    //handle CustomException2 type errors here 
} 
catch (Exception ex) 
{ 
    //handle all other types of exceptions here 
} 

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

3

Я не уверен, почему «технически», но позволяет сказать, что у меня есть приложение/веб-сайт, который использует разрешения. Если кто-то не имеет правильного разрешения, его глупость бросить исключение DivideByZero или исключение IOException. Вместо этого я могу создать мое AccessDeniedException, которое поможет мне отлаживать позже.

18

Так что вы также можете бросить их самостоятельно, а затем поймать их и узнать точно что они означают.

Также: если вы создаете библиотеку классов/framework/api, часто бывает полезно создать исключение BaseException, из-за которого наследуются другие исключения в коде. Затем, когда ваш код вызывает исключения, программисты, которые его используют, могут быстро узнать источник исключения.

9

Потому что это может сделать ваши намерения понятными, и вы также можете отслеживать использование с использованием функциональных возможностей IDE. Скажем, что у вас есть пользовательская бэкэнд-система под названием «FooBar», и вы создаете «FooBarDownException», вы можете отслеживать использование этого исключения, чтобы идентифицировать любую пользовательскую логику, содержащую ваше приложение, потому что FooBar не работает. Вы можете выбрать этот особый тип исключения и игнорировать другие, избегая перегрузок и условной логики в обработчиках исключений. Это действительно просто еще одна версия сильной печати. Это также означает, что вы можете избежать комментариев в своем коде, потому что у исключения есть намерение, раскрывающее имя.

+1

Я бы не сказал, что функциональность IDE - это точка продажи, но сделать четкие намерения - самая важная причина. – casperOne

+1

IMHO сильная печать позволяет действительно * работать * с кодом и сделать его лучше, средством для непрерывного рефакторинга. Поэтому инструментарий важен. – krosenvold

+0

Что это означает, делая намерения понятными? Я могу узнать об использовании дорожек, так как это найдет все области, которые могут быть реализованы, поскольку FooBar не работает (стандартный тип исключения, например ArgumentException, во многих разных случаях не будет предлагать это преимущество). – dotnetdev

3

По той же причине вы бы создали разные коды выхода для приложения не.NET: для указания различных ошибок, специфичных для приложения. Как ... ConnectionBrokenException или um ... UserSmellsBadException ... или что-то в этом роде.

Таким образом, вы можете точно знать, что пошло не так, и действовать надлежащим образом. Например, если вы попытаетесь отправить некоторые данные, а класс переноса данных выдает ConnectionBrokenException, вы можете открыть диалоговое окно повторного подключения и попытаться снова подключиться. Затем метод повторного подключения будет вызывать ConnectionTimeoutException, если он истечет, и вы можете снова действовать соответствующим образом.

1

Стандартные исключения .NET не покрывают все плохое, что может пойти не так в любом приложении и не предназначено. Если ваша программа не очень проста, вероятно, вам придется создать хотя бы несколько пользовательских исключений.

2

Как писал Джоэл: «Вы также можете бросить их сами, а затем поймать их и точно знать, что они означают.

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

35

Я сделал длинный пост в блоге на эту тему в последнее время:

http://blogs.msdn.com/jaredpar/archive/2008/10/20/custom-exceptions-when-should-you-create-them.aspx

Суть его сводится к тому: создать специальное исключение только если один из следующих условий

  1. Вы действительно ожидаете, что кто-то справится с этим.
  2. Вы хотите зарегистрировать информацию о конкретной ошибке
0

С одной стороны, Исключения реализованы в Библиотеке, а не на языке - как они могут создавать исключения в библиотеке? Я уверен, что вы не отстаиваете, что системные библиотеки должны иметь другой набор правил.

С другой стороны, на самом деле можно использовать дерево объектов исключений. Унаследованные исключения могут иметь специальные атрибуты, если хотите - их можно использовать для более сложных вещей, чем они есть. Я не сторонник их использования в качестве механизма передачи данных общего характера или чего-то еще (хотя они могут быть), но я мог видеть случай, когда кто-то реализовал специальное решение для регистрации, которое требовало специального атрибута в Exception ...

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

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

0

Вы не должны, если встроенные исключения надлежащим образом описывают проблему/исключение. Я бы не стал создавать собственные базовые классы для создания пользовательских ArgumentException, ArgumentNullException или InvalidOperationException.

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

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

2

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

Я писал об этом особом случае:

http://blog.mikecouturier.com/2010/01/creating-custom-exceptions-in-net-right.html

+0

Мне не нравится использование 'InvalidOperationException' (или, на самом деле, большинства исключений Framework) для условий, с которых вызывающий может попытаться обработать и восстановить. Проблема в том, что даже если метод документирован как «InvalidOperationException» в каком-то известном состоянии системы, также возможно, что некоторые внутренние методы могут вызывать «InvalidOperationException», когда состояние системы повреждено. Слишком плохо, что ни один из языков .net или Java не разрешает исключениям быть объявленными как «отмечены» на сайте броска, причем семантика может ... – supercat

+0

... указать, что оператор catch должен только catch проверенных исключений и что проверенные исключения, которые не были пойманы или иным образом помечены, чтобы быть переданными по цепочке вызовов, станут неконтролируемыми исключениями (так что «catch», окружающий вызов метода 'Foo()', может легко отличить «InvalidOperationException» 'который был выброшен по той причине, что' Foo() 'ожидает, по сравнению с тем, который был брошен внутренним методом по причинам' Foo() 'не ожидал. – supercat

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