C # не вводит исключение после использования throw - PullRequest
0 голосов
/ 17 февраля 2019

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

static void Main(string[] args)
    {
        ushort var = 65535;
        try
        {
            checked { var++; }
        }
        catch (OverflowException)
        {
            Console.WriteLine("Hello!");
            throw;
        }
        catch
        {
            Console.WriteLine("Here I am!");

        }
    }

Я ожидал, что программа выполнит следующие действия:

  • Попытка var ++, сбой и создание исключения OverflowException;
  • Enter Catch (OverflowException) инапишите "Hello!";
  • Бросьте исключение и введите catch;
  • Напишите "Вот я!".

Однако я попал только на экран "Здравствуйте! ".

РЕДАКТИРОВАТЬ: Спасибо тем, кто прокомментировал.Я думаю, что начинаю понимать.Однако моя путаница возникла из-за этой книги, которую я читаю: C # 4.0.

Я мог бы показать текст, однако это на португальском языке.Я собираюсь перевести то, что там написано: «Иногда полезно распространить исключение через несколько уловов. Например, давайте добавим, что необходимо показать конкретное сообщение об ошибке из-за того, что« idade »недопустим, но нам все еще нужно закрыть программу, являющуюся этой частью в глобальном перехвате. В этом случае необходимо распространить исключение после выполнения первого блока перехвата. Для этого вам нужно всего лишь сделать простой бросокбез аргументов. "

Пример из книги

В этом примере книги вы можете увидеть, как программист делает то же самое, что и я.По крайней мере, это выглядит так.Я что-то пропустил?Или книга не так?

Надеюсь, вы мне поможете.Спасибо!

Ответы [ 3 ]

0 голосов
/ 17 февраля 2019

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

Обработка исключений (Руководство по программированию в C #)

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

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

Это все, что вам нужно, вам понадобится еще один слой (внутренний или внешний) с try catch, чтобы поймать исключение, которое выбрасывается в catch (OverflowException)

0 голосов
/ 18 февраля 2019

Вы получите ожидаемый результат, если вложите try/catch блоки:

static void Main(string[] args)
{
    try
    {
        ushort var = 65535;
        try
        {
            checked { var++; }
        }
        catch (OverflowException)
        {
            Console.WriteLine("Hello!");
            throw;
        }
    }
    catch
    {
        Console.WriteLine("Here I am!");
    }
}
0 голосов
/ 17 февраля 2019

У меня есть две статьи по обработке исключений, на которые я часто ссылаюсь.Я лично считаю, что они должны читать при работе с ними:

https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/

https://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET

Что касается этого случая, вы не бросаете исключениеВы повторно бросаете того, кого поймали.Думайте об этом как о рыбаке, делающем «поймай и отпусти».Он может быть использован для некоторых сценариев, например, на этот раз я написал замену TryParse для кого-то, кто застрял в .NET 1.1:

//Parse throws ArgumentNull, Format and Overflow Exceptions.
//And they only have Exception as base class in common, but identical handling code (output = 0 and return false).

bool TryParse(string input, out int output){
  try{
    output = int.Parse(input);
  }
  catch (Exception ex){
    if(ex is ArgumentNullException ||
      ex is FormatException ||
      ex is OverflowException){
      //these are the exceptions I am looking for. I will do my thing.
      output = 0;
      return false;
    }
    else{
      //Not the exceptions I expect. Best to just let them go on their way.
      throw;
    }
  }

  //I am pretty sure the Exception replaces the return value in exception case. 
  //So this one will only be returned without any Exceptions, expected or unexpected
  return true;

}

Но, как правило, вы должны использовать такие вещи, как блоки "finally"для работы по уборке, а не поймать и отпустить.бросок внутри блока catch - это то, что вы редко используете.

...