C#规范整理·异常与自定义异常

本文介绍了C#编程中异常处理的规范,包括使用抛出异常代替返回错误代码,避免在不恰当的场合引发异常,正确使用Inner Exception,避免在finally块中写无效代码,以及如何处理多线程异常等。强调了异常处理在提高代码可读性和错误管理方面的重要性,并给出了具体的代码示例。
摘要由CSDN通过智能技术生成

前言

迄今为止,CLR异常机制让人关注最多的一点就是“效率”问题。其实,这里存在认识上的误区,因为正常控制流程下的代码运行并不会出现问题,只有引发异常时才会带来效率问题。基于这一点,很多开发者已经达成共识: 不应将异常机制用于正常控制流中。 达成的另一个共识是: CLR异常机制带来的“效率”问题不足以“抵消”它带来的巨大收益。

CLR异常机制至少有以下几个优点:

  • 正常控制流会被立即中止,无效值或状态不会在系统中继续传播。
  • 提供了统一处理错误的方法。
  • 提供了在构造函数、操作符重载及属性中报告异常的便利机制。
  • 提供了异常堆栈,便于开发者定位异常发生的位置。

另外,“异常”其名称本身就说明了它的发生是一个小概率事件。所以,因异常带来的效率问题会被限制在一个很小的范围内。实际上,try catch所带来的效率问题几乎是可以忽略的。在某些特定的场合,如Int32的Parse方法中,确实存在着因为滥用而导致的效率问题。在这种情况下,我们就应该考虑提供一个TryParse方法,从设计的角度让用户选择让程序运行得更快。另一种规避因为异常而影响效率的方法是:Tester-doer模式

正文

1.用抛出异常代替返回错误代码

在异常机制出现之前,应用程序普遍采用返回错误代码的方式来通知调用者发生了异常。本建议首先阐述为什么要用抛出异常的方式来代替返回错误代码的方式。对于一个成员方法而言,它要么执行成功,要么执行失败。成员方法执行成功的情况很容易理解,但是如果执行失败了却没有那么简单,因为我们需要将导致执行失败的原因通知调用者。抛出异常和返回错误代码都是用来通知调用者的手段。

但是当我们想要告诉调用者更多细节的时候,就需要与调用者约定更多的错误代码。于是我们很快就会发现,错误代码飞速膨胀,直到看起来似乎无法维护,因为我们总在查找并确认错误代码。

在没有异常处理机制之前,我们只能返回错误代码。但是,现在有了另一种选择,即使用异常机制。如果使用异常机制,那么最终的代码看起来应该是下面这样的:

static void Main(string[]args)
{    
try  
  {   
     SaveUser(user); 
   }    
catch(IOException)   
   {       
    //IO异常,通知当前用户 
   }    
catch(UnauthorizedAccessException)
    {       
    //权限失败,通知客户端管理员  
    }    
catch(CommunicationException) 
    {        
   //网络异常,通知发送E-mail给网络管理员  
    }
}

private static void SaveUser(User user)
{   
  SaveToFile(user); 
  SaveToDataBase(user);
}

使用CLR异常机制后,我们会发现代码变得更清晰、更易于理解了。至于效率问题,还可以重新审视“效率”的立足点:throw exception产生的那点效率损耗与等待网络连接异常相比,简直微不足道,而CLR异常机制带来的好处却是显而易见的。

这里需要稍加强调的是,在catch(CommunicationExcep-tion)这个代码块中,代码所完成的功能是“通知发送”而不是“发送”本身,因为我们要确保在catch和finally中所执行的代码是可以被执行的。换句话说,尽量不要在catch和finally中再让代码“出错”,那会让异常堆栈信息变得复杂和难以理解。

在本例的catch代码块中,不要真的编写发送邮件的代码,

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值