none
Когда стоит создать свой класс исключения, а когда использовать имеющийся? RRS feed

  • Вопрос

  • Есть статья в MSDN - Лучшие методики обработки исключений. Там есть абзац

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

    В оригинале

    "In most cases, use the predefined exceptions types. Define new exception types only for programmatic scenarios. Introduce a new exception class to enable a programmer to take a different action in code based on the exception class."

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

    • Перемещено Abolmasov Dmitry 28 декабря 2011 г. 13:37 (От:Настольные ПК)
    29 ноября 2011 г. 14:55

Ответы

  • В C# нет When в catch. Если бросать только один тип исключения - то отладка чего-то крупного становится нетривиальной задачей. Сейчас в отладчике можно включить остановку при бросании EmptySquareException (именно при бросании, а не на первой строке catch). Если бросать просто Exception - то отладчик будет останавливаться везде подряд, и вы до проблемного места никогда не доберетесь.

    Навскидку - ArgumentException добавляет имя неправильного параметра.

    Делайте новый класс, если конкретное место и конкретное исключение несет какую-то особую смысловую нагрузку в вашем приложении.
    29 ноября 2011 г. 18:09
    Модератор

Все ответы

  • Я так думаю, под сценарием тут понимается обработка catch в вызывающем коде.

    Допустим я создал класс Square, который имеет метод Paint.

    Теперь я хочу что бы при нулевом размере квадрата, метод Paint выбрасывал исключение. Если я буду выбрасывать просто Exception, то как вызывающий код поймет, что проблема именно в размераз квадрата, а не в том, например, что не задан цвет квадрата? Поэтому, если я хочу сообщить вызывающему коду некую дополнительную информацию, что бы он смог ее обработать (тот самый "программный сценарий"), я должен создать свой тип исключений.

    Тогда вызов может быть типа такого:

    try{
      square.Paint();
    }catch(EmptySquareException)
    {
      //тут мы понимаем, что проблема в размерах квадарата
    }
    catch(Exception)
    {
      //а тут мы не знаем что именно случилось, просто не смог отрисоваться почему-то
    }
    

    29 ноября 2011 г. 17:01
    Отвечающий
  • ... Если я буду выбрасывать просто Exception, то как вызывающий код поймет, что проблема именно в размераз квадрата, а не в том, например, что не задан цвет квадрата? Поэтому, если я хочу сообщить вызывающему коду некую дополнительную информацию, что бы он смог ее обработать (тот самый "программный сценарий"), я должен создать свой тип исключений. ...

    Да, но что мешает в таком случае Exception.Data и задать нужно свойство там? Тогда Блок catch содержал бы when, чтобы отфильтровать нужный случай.

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

    Тогда вопрос остается открытым. Когда стоит делать новый класс?

    29 ноября 2011 г. 17:28
  • В C# нет When в catch. Если бросать только один тип исключения - то отладка чего-то крупного становится нетривиальной задачей. Сейчас в отладчике можно включить остановку при бросании EmptySquareException (именно при бросании, а не на первой строке catch). Если бросать просто Exception - то отладчик будет останавливаться везде подряд, и вы до проблемного места никогда не доберетесь.

    Навскидку - ArgumentException добавляет имя неправильного параметра.

    Делайте новый класс, если конкретное место и конкретное исключение несет какую-то особую смысловую нагрузку в вашем приложении.
    29 ноября 2011 г. 18:09
    Модератор
  • Добавлю еще, что Exception.Data не может полноценно заменить типизрованные исключения. Дело в том, что классы исключений можно наследовать. Например, я могу сделать базовое исключение EmptyFigureException, а потом от него унаследовать исключения EmptySquareException и EmptyCircleException. А потом в коде я могу ловить и общее для всех фигур исключение (EmptyFigureException) и специализированое для конкретной фигуры исключение:

    try{
      square.Paint();
    }catch(EmptySquareException)
    {
      //тут мы ловим пустые квадраты
    }
    catch(EmptyFigureException)
    {
      //а тут ловим любые другие пустые фигуры
    }
    

    А как вы это сделаете с Data ?

    >Да, но что мешает в таком случае Exception.Data и задать нужно свойство там

    Ничего не мешает. Можно вообще отказаться от классов и типизированных полей, а хранить все данные в IDictionary. Только нафик такое счастье? C# это сильно типизированный язык и нужно использовать его преимущества - автоматический контроль типов в compile time и автоматический рефакторинг. А какой контроль будет в IDictionary? Никакого.

     

    29 ноября 2011 г. 23:24
    Отвечающий
  • Добавлю еще, что Exception.Data не может полноценно заменить типизрованные исключения. Дело в том, что классы исключений можно наследовать. Например, я могу сделать базовое исключение EmptyFigureException, а потом от него унаследовать исключения EmptySquareException и EmptyCircleException. А потом в коде я могу ловить и общее для всех фигур исключение (EmptyFigureException) и специализированое для конкретной фигуры исключение:

     

    try{
      square.Paint();
    }catch(EmptySquareException)
    {
      //тут мы ловим пустые квадраты
    }
    catch(EmptyFigureException)
    {
      //а тут ловим любые другие пустые фигуры
    }
    

     

    А как вы это сделаете с Data ?

    Как мне здесь уже написали, это можно сделать только в Visual Basic. В C# однозначно только через классы. Так что, видимо, еще и язык накладывает свой отпечаток на принятое решение.
    30 ноября 2011 г. 10:48
  • Поднимаю тему, но все же.

    Вопрос по исключениям- что делать в блоке catch? Обычно в примерах там пишут Console.WriteLine("Error");

    А в реальных проектах?

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

    Можете написать реальный пример обработки исключений?

    Спасибо.

    31 июля 2013 г. 16:40