为什么要适当的捕捉异常呢?如下代码,因为我们不能什么异常都去捕捉,在捕获异常后,我们需要去处理这些异常,如果我们将所有的异常都捕捉后,但是没有预见会发生的异常,我们就没有办法去处理这些异常。
如果应用程序代码抛出一个异常,应用程序的另一端则可能预期要捕捉这个异常,因此不能写成一个”大小通吃“的异常块,应该允许该异常在调用栈中向上移动,让应用程序代码针对性地处理这个异常。
在catch块中,可以使用System.Exception捕捉异常,但是最好在catch块末尾重新抛出异常。至于原因在后面会讲解到。
try
{
var hkml = GetRegistryKey(rootKey);
var subkey = hkml.CreateSubKey(subKey);
if (subkey != null && keyName != string.Empty)
subkey.SetValue(keyName, keyValue, RegistryValueKind.String);
}
catch (Exception ex)
{
Log4Helper.Error("创建注册表错误" + ex);
throw new Exception(ex.Message,ex);
}
3.从异常中恢复:
我们在捕获异常后,可以针对性的写一些异常恢复的代码,可以让程序继续运行。在捕获异常时,需要捕获具体的异常,充分的掌握在什么情况下会抛出异常,并知道从捕获的异常类型派生出了那些类型。除非在catch块的末尾重新抛出异常,否则不要处理或捕获System.Exception异常。
4.维持状态:
一般情况下,我们完成一个操作或者一个方法时,需要调用几个方法组合完成,在执行的过程中会出现前面几个方法完成,后面的方法发生异常。发生不可恢复的异常时回滚部分完成的操作,因为我们需要恢复信息,所有我们在捕获异常时,需要捕获所有的异常信息。
5.隐藏实现细节来维持契约:
有时可能需要捕捉一个异常并重新抛出一个不同的异常,这样可以维系方法的契约,抛出的心异常类型地应该是一个具体的异常。看如下代码:
FileStream fs = null;
try
{
fs = FileStream();
}
catch (FileNotFoundException e)
{
//抛出一个不同的异常,将异常信息包含在其中,并将原来的异常设置为内部异常
throw new NameNotFoundException();
}
catch (IOException e)
{
//抛出一个不同的异常,将异常信息包含在其中,并将原来的异常设置为内部异常
throw new NameNotFoundException();
}
finally
{
if (fs != null)
{
fs.close();
}
}
以上的代码只是在说明一种处理方式。应该让抛出的所有异常都沿着方法的调用栈向上传递,而不是把他们”吞噬“了之后抛出一个新的异常。如果一个类型构造器抛出一个异常,而且该异常未在类型构造器方法中捕获,CLR就会在内部捕获该异常,并改为抛出一个新的TypeInitialztionException。








