C#中异常使用的注意事项

发表于:2012-5-31 09:32

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Luminji    来源:51Testing软件测试网采编

  一、两个立足点

  1、正常控制流程下的代码运行并不会带来问题,只有引发异常才会带来效率问题。

  2、不应将异常机制用于正常控制流中。

  二、需要引发异常的四类情况

  第一类情况是:如果运行代码后,造成内存泄漏、资源不可用或应用程序状态不可恢复,则引发异常。Console这个类中,有很多类似这样的代码:

if((value<1)||(value>100))
        {
thrownewArgumentOutOfRangeException("value", value, Environment.GetResourceString("ArgumentOutOfRange_CursorSize"));
        }

  Console这个类虽然也提供了Tester-Doer模式,让调用者可以有更多的方法来验证输入。但是永远不要保证调用者对你的类有足够的了解,他有可能调用你的任何公开方法,而不会考虑先后顺序;所以应该为这类方法引发一些必要的异常。但是,如果你自己写了一个Student业务类,判断年龄,年龄小于0这样的判断,就不应该引发异常,因为那是一个正常控制流。

  第二类需要引发异常的情况是:在捕获异常的时候,如果需要包装一些更有用的信息,则引发异常。这类异常的引发在UI层特别有用。系统引发的异常所带的Message往往更倾向于技术性的描述,而在UI层,异常的用户很可能是最终用户。如果我们需要将异常的Message信息呈现给最终用户,更好的做法是包装异常,然后引发一个含有友好信息的新异常。

  第三类情况:如果底层异常在高层操作的上下文中没有意义,则可以考虑捕获这些底层异常,并引发新的有意义的异常。如将一个InvalidCastException引发为新的ArgumentException。

  第四类正确引发异常的一个典型的例子就是捕获底层API错误代码,并抛出。Console为我们封装了调用windows api返回的错误代码,而让代码引发一个新的异常。

  三、避免throw中将异常堆栈信息吃掉

  代码应该看起来是这样的:

try
{
   (new NestedExceptionSample2()).MethodWithTry2();
}
catch (Exception)
{
    //do something
    throw;
}

  或者:

try
{
    (new NestedExceptionSample2()).MethodWithTry2();
}
catch 
{
     //do something
     throw;
}

  尽量避免像下面这样引发异常:

catch(Exception err)
{
    
//do something
    throw  err;
}

  直接throw err而不是throw将会重置堆栈信息。

  四、处理未捕获异常和多线程异常

  这在我的另一篇博文中已经论述:异常处理之ThreadException、unhandledException及多线程异常处理

  五、避免在调用栈较低位置记录异常

  最适合进行异常记录和报告的是应用程序的最上层,这通常是UI层。假设存在这样的一个应用程序,它的BLL层,即可能被一个Winform窗口程序调用,也可能被一个控制台应用程序调用,那么如果要在BLL模块向管理员报告异常的时候,你不知该使用MessageBox方法还是Console.Write方法。

  如果异常在调用栈的较低位置被记录或报告,且还存在被包装后重新抛出的情况,这就会让记录重复出现。

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号