引发异常只是为了处理确实异常的情况,而不是为了处理可预知的事件或流控制。所选择的方法依赖于预计事件发生的频率。如果事件确实是异常的并且是一个错误(如意外的文件尾),则使用异常处理比较好,因为正常情况下执行的代码更少。如果事件是例行发生的,使用编程方法检查错误比较好。在此情况下,如果发生异常,将需要更长的时间处理。
一、 避免异常
可以以编程方式检查可能发生的条件,不使用异常处理。因为引发或处理异常时,将使用大量的系统资源和执行时间。如:
1、类型转换前先判断。如:
Int32.TryParse(val, out a);
return a;
///代替
int a = 0;
try
{
a = int.Parse(val);
return a;
}
catch { }
return a;
2、变量与对象引用前做NULL判断等。
if(!string.IsNullOrEmpty(userName))
{
///
}
if(userModel!=null)
{
///
}
3、以以编程方式检查可能发生的条件,而不使用异常处理
if(conn.State != ConnectionState.Closed)
conn.Close();
///代替
try
{
conn.Close();
}
catch(InvalidOperationException ex) {
//Do something with the error or ignore it.
}
4、只在必要的时候引发异常。对非常常见的错误情况返回空,记录错误信息而不引发异常。
二、抛出异常
l 如果根据对象的当前状态,属性集或方法调用不适当,则引发 InvalidOperationException。
l 如果传递无效的参数,则引发 ArgumentException 或从 ArgumentException 派生的类。
l 堆栈跟踪从引发异常的语句开始,到捕捉异常的 Catch 语句结束。当决定在何处放置 Throw 语句时需考虑这一点。
l 引发异常,而不是返回错误代码或 HRESULT。
三、捕获异常
l 高层(UI层)抛出异常。除非是下列情况之一:
1、 能够处理该异常,或者
2、 能够忽略该异常,或者
3、 需要转换该异常为其它特定异常后抛出新异常
l UI层在基类或Global中统一捕获异常。除非是下列情况之一:
1、 将无关紧要的异常忽略。
2、 将异常转换为错误信息展现给用户。
3、 如果是重大异常,可以考虑终止应用程序。
l 引发异常时清理中间结果。当异常从方法引发时,调用方应该能够假定没有副作用。
l 在可潜在生成异常的代码周围使用 Try/Finally 块,并将 Catch 语句集中在一个位置。以这种方式,Try 语句生成异常,Finally 语句关闭或释放资源,而 Catch 语句从中心位置处理异常。
l 始终按从最特定到最不特定的顺序对 Catch 块中的异常排序。
四、自定义异常
l 在大多数情况下,使用预定义的异常类型。仅为编程方案定义新异常类型。引入新异常类,使程序员能够根据异常类在代码中采取不同的操作。
l 以“Exception”这个词作为异常类名的结尾。
public class MyFileNotFoundException : Exception
{
///
}
l 如果是自定义异常,请保证其是可序列化的,并且保证其实现了Exception的三个构造函数。
using System;
public class EmployeeListNotFoundException: Exception
{
public EmployeeListNotFoundException()
{
}
public EmployeeListNotFoundException(string message)
: base(message)
{
}
public EmployeeListNotFoundException(string message, Exception inner)
: base(message, inner)
{
}
}
本文探讨了如何合理地使用异常处理来提升代码质量。包括避免异常的编程方式、何时抛出异常、如何捕获异常以及创建自定义异常等内容。

1134

被折叠的 条评论
为什么被折叠?



