在C#的try/catch块中检查异常类型

3

我有一个非常基础的问题一直在思考。

请参考以下使用 try/catch 块的代码片段:

public void doSomething()  
{  
   try
    {
        doSomethingElse()
    }
    catch (Exception ex)
    {
        if (ex is IndexOutOfRangeException || ex is DivideByZeroException || ex is Exception)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

1) 如果我只想将异常消息输出到控制台,是否需要在if语句中检查我获取的异常类型,还是可以直接执行以下操作:

```` try { // some code here } catch (Exception e) { System.out.println(e.getMessage()); } ````
...
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
...

2) 我的理解是,如果我需要在控制台上输出一个定义好的消息而不是使用异常消息本身,那么应该检查特定的异常类型 - 大致如下:

...
    catch (Exception ex)
    {
        switch (ex):
        {
            case IndexOutOfRangeException:
                Console.WriteLine("Personalized message #1");               
                break;
            case DivideByZeroException:
                Console.WriteLine("Personalized message #2");               
                break;
            case Exception:
                Console.WriteLine("Personalized message #3");               
                break;
        }
    }
...

非常感谢您对1)和2)的评论。感谢您的时间。

"|| ex is Exception" 总是返回 true,所以这个 if 语句有点没用。 - Dennis_E
你不需要知道异常的类型就能输出其消息,但更大的问题是你永远不应该仅仅忽略异常,我认为捕获Exception也是一个很大的代码异味。对于日志记录,或许可以这样做,但我仍然会尝试捕获我知道是安全的日志记录异常。 - Lasse V. Karlsen
@LasseV.Karlsen 请问您能否澄清"忽略异常"和"代码异味"的含义?(对于这个愚蠢的问题很抱歉) - gacanepa
5个回答

8

1) 如果我只想将异常消息输出到控制台,是否有必要在if语句中检查我收到的异常类型?

不需要检查每个异常类型,如果您只想显示其消息,请使用 Exception.Message 属性。

2) 我的理解是,如果我需要向控制台输出定义的消息而不是使用异常消息本身,则应检查特定的异常类型

与其捕获基本异常,然后比较每种不同类型,最好首先捕获特定的异常,然后在每个catch块的最后捕获基本异常

try
{

}
catch (IndexOutOfRangeException indexOutOfRangeException)
{
      //Specific handling
}
catch (DivideByZeroException divideByZeroException)
{
      //Specific handling
}
catch (Exception ex)
{
      //Exception handling for all other cases
}

2

第一点是正确的。

关于第二点,不需要使用switch。相反,您可以这样做:

try
{
    doSomethingElse()
}
catch (IndexOutOfRangeException)
{
    Console.WriteLine("Personalized message #1");               
}
catch (DivideByZeroException)
{
    Console.WriteLine("Personalized message #2");               
}
catch (Exception)
{
    Console.WriteLine("Personalized message #3");               
}

1

在异常处理中,应该从最具体的异常到更通用的异常(因此 Exception 最后处理)。

甚至可以在 catch 中重新抛出异常并修改消息(如果需要)。

正确的做法是:

try{
}catch(IndexOutOfRangeException e){
    LOGGER.errorFormat("This is an error {0}", e.Message);
    LOGGER.debugFormat("More infor on the exception {0}", e.StackTrace);
}catch(DivideByZeroException ex){
    LOGGER.errorFormat("This is an error {0}", ex.Message);
    LOGGER.debugFormat("More infor on the exception {0}", ex.StackTrace);
    throw new Exception("This is custom message");
}...
catch(Exception eex){
}

0
如果我只想将异常消息输出到控制台,是否有必要在 if 语句中检查我获取的 Exception 类型,还是可以直接执行?
不需要,你可以直接执行。
我理解的是,如果我需要输出定义的消息而不是使用异常消息本身,应该检查特定的异常类型 - 大致如此。
它应该用于以不同的方式处理异常。但更重要的是,您应该使用 catch 来处理您不希望遇到的异常,而不是处理程序流程(这就是我想象您尝试使用个性化消息处理的内容)。相反,您应该设置错误处理来捕获导致异常的事物,使其永远不会到达那里。
catch(IndexOutOfRangeException)

提前使用

if(currentIndex < something.Length)
     //do my thing

如果这是来自用户输入的,你可以通过其他方式验证currentIndex


0

我建议不要使用ex.Message,而是直接使用ex.ToString()。就我所知,这会提供有关异常的所有信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接