Как отличить разные простые исключения? - PullRequest
1 голос
/ 20 февраля 2011

Если я не хочу создавать пользовательские исключения, то как их различить при отлове?

if (somethingIsWrong)
   throw new Exception("Something is wrong.");
else if (anotherthingIsWrong)
   throw new Exception("Anotherthing is wrong.");
else
   throw Exception("Nothing is wrong!");

// Now when catching them:

catch (Exception ex)
{
   if (ex.Message.Contains("Something"))
      ShowUserErrorThatSomethinIsWrong();
   else if (ex.Message.Contains("Another"))
      ShowUserErrorThatAnotherthinIsWrong();
   // ...
}

Мне бы хотелось, чтобы System.Exception имел свойство ErrorNumber для настройки исключений следующим образом:

if (somethingIsWrong)
   throw new Exception(1001, "Something is wrong.");

// And catching them this way:

if (ex.ErrorNumber = 1001)
   // ...

Я знаю, что можно расширить MyExceptionClass с System.Exception, но есть ли лучшее решение?

Это связано с моим другим вопросом, который вы можете найти здесь .

Ответы [ 5 ]

4 голосов
/ 20 февраля 2011

Создание собственного типа исключения - это решение здесь.

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

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

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

1 голос
/ 20 февраля 2011

Создание пользовательских исключений путем расширения System.Exception - это ПУТЬ. Почему ты не хочешь этого делать?

Преимущества:

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

Есть ли веская причина не использовать этот подход?

1 голос
/ 20 февраля 2011

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

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

0 голосов
/ 20 февраля 2011

Я бы сказал, что лучше не выбрасывать Exception объекты, потому что они слишком общие. Есть много классов, которые наследуются от Exception внутри фреймворка, обычно это тот, который соответствует сценарию, в котором вы находитесь. Если нет, тогда расширьте Exception своим собственным классом.

Например, если вы проверяете параметры, входящие в метод, и обнаруживаете, что один из них равен нулю, а это не так, бросьте ArgumentNullException. Если две вещи пытаются быть выполнены не по порядку, бросьте InvalidOperationException. Вы можете поймать эти исключения индивидуально:

try
{
}
catch (ArgumentNullException argException)
{
}
catch (InvalidOperationException opException)
{
}

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

0 голосов
/ 20 февраля 2011

Ну, вы "должны" создавать свои собственные исключения в .NET. Модель исключения работает лучше всего таким образом.

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

public class ErrorCodeException : Exception
{
    private readonly int _errorCode;
    public ErrorCodeException(int errorCode)
    {
        _errorCode = errorCode;
    }

    public ErrorCodeException(int errorCode, string message)
        : base(message)
    {
        _errorCode = errorCode;
    }

    public int ErrorCode { get { return _errorCode; } }
}

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

...