Обработка исключений C # провалилась [дубликаты]

Если у вас есть приложение WPF или Silverlight, убедитесь, что App.xaml имеет «ApplicationDefinition» как BuildAction для свойств файла.

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

8 ответов

Проблема с синтаксисом, как упоминалось (с ex ): какие свойства / члены должны иметь ex ? Различные типы исключений не обязательно совместимы, если только не задействовано наследование (в этом случае поймайте наименее производные, которые вас интересуют).

Единственный текущий вариант - просто использовать Exception ex (или аналогично) и проверьте ( это / как ) внутри обработчика.

Или; преобразовать общий код в метод, который может использоваться всеми тремя?

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

Короче нет. Я могу придумать две три альтернативы:

Перехватить каждое исключение и вызвать общий метод:

try
{
   // throw
}
catch ( ExceptionTypeA ex )
{
     HandleException();
}
catch ( ExceptionTypeB ex )
{
     HandleException();
}
catch ( ExceptionTypeC ex )
{
     HandleException();
}

void HandleException()
{
}

Или перехватить все и использовать оператор if для типа:

try
{
   // throw
}
catch (Exception ex)
{
   if (ex is ArgumentException || ex is NullReferenceException || ex is FooException)
   {
      // Handle
   }
   else
   {
      throw
   }
}

EDIT: ИЛИ, вы можете сделать что-то вроде этого:

List<Type> exceptionsToHandle = new List<Type>{ typeof(ArgumentException), typeof(NullReferenceException), typeof(FooException) };

try
{
   // throw
}
catch (Exception ex)
{
   if (exceptionsToHandle.Contains(ex.GetType()))
   {
      // Handle
   }
   else
   {
      throw
   }
}
9
ответ дан 1 December 2019 в 06:59
поделиться

Оберните повторяющийся код в метод.

try
{
...
}
catch ( ExceptionTypeA ex )
{
     DoSomething();
}
catch ( ExceptionTypeB ex )
{
     DoSomething();
}
catch ( ExceptionTypeC ex )
{
     DoSomething();
}
catch ( Exception ex )
{
     DoTheDefaultSomething();
}
4
ответ дан 1 December 2019 в 06:59
поделиться

If you need to use some variables from the scope of try, use a nested function. That is, a lambda or an anonymous delegate:

int x = ...;
Action<Exception> handler = delegate(Exception ex)
{
    // Same code for all exceptions of A, B or C.
    // You can use variable x here too.
};    

try
{
...
}
catch (ExceptionTypeA ex) { handler(ex); }
catch (ExceptionTypeB ex) { handler(ex); }
catch (ExceptionTypeC ex) { handler(ex); }
3
ответ дан 1 December 2019 в 06:59
поделиться

Вы могли бы получить TypeA, B, C из общего базового класса, если это разумно. И перехватить исключение базового класса.

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

Не чистый путь. Вы могли просто перехватить System.Exception, а затем проверить тип во время выполнения, то есть

try
{
...
}
catch (System.Exception ex)
{
   if (ex is ExceptionTypeA or ExceptionTypeB or ExceptionTypeC)
   {
       ... same code ...
   }
   else
       throw;
}

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

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

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

catch (Exception ex)            
   {                
      if (ex is ExceptionTypeA ||
          ex is ExceptionTypeB )
           {
               /* your code here */
           }
       else
           {
               throw;
           }
    }

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

if (ex is ExceptionTypeA || ex is ExceptionTypeB )

получилось бы что-то вроде:

if (IsRecoverableByDoingWhatever(ex))

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

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

If you have access to the code that define the custom exceptions, one possible solution is:

Create a custom exception type.

public abstract class CustomException : Exception
{
        //Do some stuff here
}

Then make all your custom exceptions derive from this base type:

public class MyException1 : CustomException
{
        // Do some stuff here
}

public class MyException2 : CustomException
{
    // Do some stuff here
}

You are done. So now, all you need in your client code is to catch the custom exception base class.

try
{
     //Do something that throws a custom exception
}
catch (CustomException ex)
{
     // Do some shared behavior for all the custom exceptions
}   
1
ответ дан 1 December 2019 в 06:59
поделиться
Другие вопросы по тегам:

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