C#异常处理失败

时间:2009-11-18 21:40:24

标签: c# exception-handling

  

可能重复:
  Catch multiple Exceptions at once?

C#中有什么方法可以轻松实现以下pseduo代码:

try
{
...
}
catch ( ExceptionTypeA, ExceptionTypeB, ExceptionTypeC as ex)
{
... same code for all threw
}

或者

try
{
...
}
catch ( ExceptionTypeA ex )
catch ( ExceptionTypeB ex )
catch ( ExceptionTypeC ex )
{
... same code for all exceptions of A, B or C
}

我想我所说的很棒将是异常类型。

8 个答案:

答案 0 :(得分:16)

提到的语法问题(使用ex)是:ex应该具有哪些属性/成员?不同的异常类型不一定兼容,除非涉及继承(在这种情况下,捕获您关心的最少派生)。

目前唯一的选择是在处理程序中使用Exception ex(或类似)并检查(is / as)。

或者;将公共代码重构为一个可以被所有三个使用的方法?

答案 1 :(得分:9)

简而言之,没有。我可以想到两个三种选择:

抓住每个异常,并调用一个常用方法:

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
   }
}

编辑:或者,您可以这样做:

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
   }
}

答案 2 :(得分:5)

您可以捕获一般异常,然后检查类型,例如:

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

编辑:与其他答案一致我希望通过提取方法来澄清发生了什么 - 但不是个别捕获和常用方法,我可能会介绍一种方法来澄清内容是什么如果声明正在做。而不是

if (ex is ExceptionTypeA || ex is ExceptionTypeB )
它变得像:

if (IsRecoverableByDoingWhatever(ex))

我认为除了提取处理程序代码之外还要澄清意图(尽管这样做也可能有用)。

答案 3 :(得分:4)

将重复代码包装在方法中。

try
{
...
}
catch ( ExceptionTypeA ex )
{
     DoSomething();
}
catch ( ExceptionTypeB ex )
{
     DoSomething();
}
catch ( ExceptionTypeC ex )
{
     DoSomething();
}
catch ( Exception ex )
{
     DoTheDefaultSomething();
}

答案 4 :(得分:3)

如果需要使用try范围内的某些变量,请使用嵌套函数。也就是说,lambda或匿名委托:

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); }

答案 5 :(得分:1)

如果合理,您可以从公共基类派生TypeA,B,C。并捕获基类异常。

答案 6 :(得分:1)

不是一个干净的方式。你可以只捕获System.Exception,然后在运行时检查类型,即

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

......但这很难看。正如JoãoAngelo所说,对于每种异常类型都有单独的catch块,但在每种异常类型中调用一个常用方法会更好。

答案 7 :(得分:1)

如果您有权访问定义自定义异常的代码,则可以采用以下解决方案:

创建自定义异常类型。

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

然后使所有自定义异常派生自此基本类型:

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

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

你完成了。所以现在,您在客户端代码中所需要的只是捕获自定义异常基类。

try
{
     //Do something that throws a custom exception
}
catch (CustomException ex)
{
     // Do some shared behavior for all the custom exceptions
}