Можно ли поймать больше чем один тип исключения с каждым блоком? [дубликат]

Социальные навыки имеют значение больше, чем технические навыки

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

15
задан Community 23 May 2017 в 12:33
поделиться

11 ответов

Вы можете использовать:

catch (SystemException ex)
{
  if(    (ex is IOException)
      || (ex is UnauthorizedAccessException )
// These are redundant
//    || (ex is PathTooLongException )
//    || (ex is DirectoryNotFoundException )
      || (ex is NotSupportedException )
     )
       lblBpsError.Text = ex.Message;
    else
        throw;
}
23
ответ дан 1 December 2019 в 00:59
поделиться

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

8
ответ дан 1 December 2019 в 00:59
поделиться

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

Что касается вашего вопроса: я не знаю способа, о котором я знаю, но есть некоторые обходные пути:

  • Дайте исключениям общего предка. Я думаю, что в вашем случае это будет невозможно, поскольку они кажутся встроенными.
  • Перехватите наиболее общее исключение, которое вы можете.
  • Переместите код обработки в его собственную функцию и вызовите ее из каждого блока catch.
3
ответ дан 1 December 2019 в 00:59
поделиться

Это раздражает, и в других ответах предлагались хорошие обходные пути (я бы использовал @ Lotfi's).

Однако такое поведение является требованием, учитывая типобезопасность C #.

Предположим, вы могли бы сделать это:

try
{
    Directory.CreateDirectory(directory);
    return true;
}
catch (IOException, 
    UnauthorizedAccessException,
    PathTooLongException,
    DirectoryNotFoundException,
    NotSupportedException ex)
{
    lblBpsError.Text = ex.Message;
}

Какой теперь тип ex ? У всех есть .Message , потому что они наследуют System.Exception , но попробуйте получить доступ к любому из их других свойств, и у вас возникнет проблема.

2
ответ дан 1 December 2019 в 00:59
поделиться

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

2
ответ дан 1 December 2019 в 00:59
поделиться

Для полноты картины:

В VB вы можете использовать условную обработку исключений:

Try
    …
Catch ex As Exception When TypeOf ex Is MyException OrElse _
                           TypeOf ex Is AnotherExecption
    …
End Try

Такой блок Catch будет вводиться только для указанных исключений - в отличие от C #.

Возможно, будущая версия C # предложит аналогичную функцию (в конце концов, для этого кода есть специальная инструкция IL).

MSDN: Как фильтровать ошибки в блоке Catch в Visual Basic

2
ответ дан 1 December 2019 в 00:59
поделиться

Вы можете перехватить исключение базового класса (все ваши исключения происходят от SystemException ):

try
{
  Directory.CreateDirectory(directory);
  return true;
}
catch (SystemException ex)
{
  lblBpsError.Text = ex.Message;
}

Но тогда вы можете перехватить исключения, которые не хотите перехватывать .

0
ответ дан 1 December 2019 в 00:59
поделиться

Вы можете выполнить

ex.GetType ()

см. http://msdn.microsoft.com/en-us/library/system.exception.gettype. aspx

РЕДАКТИРОВАТЬ

try            
{                
    Directory.CreateDirectory(directory); 
    return true;           
}            
catch (Exception ex)            
{   switch(ex.GetType())
         case .....
         case ..........
    blBpsError.Text = ex.Message;            
}
0
ответ дан 1 December 2019 в 00:59
поделиться

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

Например, используйте Directory.GetAccessControl (...) вместо того, чтобы полагаться на возникновение исключения UnauthorizedAccessException.

0
ответ дан 1 December 2019 в 00:59
поделиться

Вы можете использовать делегатов, это сделает то, что вы хотите:

РЕДАКТИРОВАТЬ: немного упрощено

static void Main(string[] args)
{
    TryCatch(() => { throw new NullReferenceException(); }, 
        new [] { typeof(AbandonedMutexException), typeof(ArgumentException), typeof(NullReferenceException) },
        ex => Console.WriteLine(ex.Message));

}

public static void TryCatch(Action action, Type[] exceptions, Action<Exception> catchBlock)
{
    try
    {
        action();
    }
    catch (Exception ex)
    {
         if(exceptions.Any(p => ex.GetType() == p))
         {
             catchBlock(ex);
         }
         else
         {
             throw;
         }
    }
}

Ваша конкретная попытка / уловка будет:

bool ret;
TryCatch(
    () =>
        {
            Directory.CreateDirectory(directory);
            ret = true;
        },
    new[]
        {
            typeof (IOException), typeof (UnauthorizedAccessException), typeof (PathTooLongException),
            typeof (DirectoryNotFoundException), typeof (NotSupportedException)
        },
    ex => lblBpsError.Text = ex.Message
);

return ret;
0
ответ дан 1 December 2019 в 00:59
поделиться

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

0
ответ дан 1 December 2019 в 00:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: