Можно ли избежать исключений в C #, продолжая выполнение кода? - PullRequest
7 голосов
/ 13 октября 2009

У меня есть следующий код C #. Всякий раз, когда обнаруживается исключение, скажем, в строке 1, я никогда не могу достичь других строк (2, 3, 4 и т. Д.).

try
{
    line1
    line2
    ...
}
catch (Exception ex)
{
    ...
}

Возможно ли в C # сказать, что если строка 1 генерирует исключение, просто перейдите к другим строкам (2, 3, 4 и т. Д.)?

Ответы [ 13 ]

16 голосов
/ 13 октября 2009

Исключения не следует игнорировать. :)
Они существуют и выбрасываются по причине: возникла исключительная ситуация, не выполнено определенное условие, и я не могу продолжать работать ...

Можно игнорировать исключения, если вы поместите блок try / catch вокруг каждой строки кода, но я не думаю, что вы действительно хотите это сделать ...

10 голосов
/ 13 октября 2009

Вы можете создать метод SkipOnError следующим образом:

private SkipOnError(Action action)
{
    try 
    {
        action();
    }
    catch
    {
    }
}

Тогда вы могли бы назвать это так:

try
{ 
    SkipOnError(() => /*line1*/);
    line2;
    line3;
} catch {}

Редактировать: Это должно упростить пропуск данного исключения:

private SkipOnError(Action action, Type exceptionToSkip)
{
    try 
    {
        action();
    }
    catch (Exception e)
    {
        if (e.GetType() != exceptionToSkip) throw;            
    }
}

ПРИМЕЧАНИЕ: На самом деле я не предлагаю вам делать это - по крайней мере, не на регулярной основе, так как я нахожу это довольно глупым. Но это как бы демонстрирует некоторые функциональные возможности, которые мы можем теперь делать в C #, ууу!

Что бы я на самом деле сделал, так это: Рефакторинг line1 в метод ( Извлечение метода ). Этот новый метод должен обрабатывать любые предсказуемые исключения (если они могут быть обработаны) и, таким образом, оставлять вызывающего в известном состоянии. Потому что иногда вы действительно хотите сделать line1, за исключением, может быть, ничего страшного, если произойдет ошибка ...

5 голосов
/ 13 октября 2009

просто попробуй поймать вокруг строки1

try
{
    try
    {
        line1
    }
    catch (Exception ex)
    {
       ...
    }

    line2
    ...
}
catch (Exception ex)
{
    ...
}

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

4 голосов
/ 13 октября 2009

Если есть код, который вы всегда хотите выполнить, даже если выдается исключение, даже если исключение либо не попадает в блок catch, либо блок catch перебрасывает или генерирует новое исключение, должен идти в блоке finally:

try
{
  do(something);
}
catch (InvalidArgumentException ex)
{
  onlyDealWithOneExceptionType();
}
finally
{
  always.runs(no, matter, what);
}
3 голосов
/ 13 октября 2009

Вы можете изолировать каждую строку в блоке try-catch, однако для меня это просто запах кодов. Если вы уверены , что строки после первой строки не генерируют исключения или должны выполняться независимо от исключения и не будут выдавать дополнительные ошибки, вы можете добавить блок finally после первый улов. Пример:

try{
  line 1;
}
catch(Exception exc){
  //Error handling logic here
}
finally{
  line 2;
  line 3;
  .
  .
  .
  line n;
}
2 голосов
/ 13 октября 2009

Вы можете обернуть только строку 1 в блоке try catch.

1 голос
/ 13 октября 2009

Для этого вам понадобятся продолжения reifiable. CLR и C # не поддерживают это и, вероятно, никогда не будут этого делать. (

1 голос
/ 13 октября 2009

Как уже говорили другие, сначала убедитесь, что «игнорирование» исключения - это то, что вы действительно хотите сделать. Если это все еще так, и синтаксические накладные расходы всех try-catch слишком велики, вы могли бы обернуть их с помощью idom для выполнения.

У меня нет времени набросать весь код прямо сейчас, но вы должны написать метод, который принимает анонимный делегат и выполняет его в режиме try-catch (может быть, регистрирует любые исключения или фильтрует их). это "хорошо"). Назовите этот метод что-то вроде tryDo. Затем вы можете написать свой код примерно так:

tryDo( delegate(){ line1; } );
tryDo( delegate(){ line2; } );

Это все еще немного многословно, но тогда вы не хотите делать это слишком простым. Достаточно накладных расходов, чтобы вы продолжали задаваться вопросом, правильно ли это делать: -)

1 голос
/ 13 октября 2009

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

Вы должны восстановиться после первого исключения, а затем перейти к следующей строке, заключив каждую из них в инструкцию try / catch.

1 голос
/ 13 октября 2009

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

...