try-catch异常处理说白了就是处理处理异常的,那么什么时候应该抛异常?比如当一个类型的成员(如方法,属性)不能完成任务时,就应抛出异常。
public bool TestFunc(string input)
{
return input.Substring(1, 1).ToUpper().EndsWith("E");
}
我们没有做任何的参数检查,而直接调用了一长串的方法。当input参数为null或空时,上面的代码就会抛出异常。即使方法为没有返回值的void型也应该报告错误。那么这时候就要用到处理异常的机制了,在.net中就叫异常处理。
语法如下
try
{ //这里是TRY开始,程序开始捕获异常
//如果有异常 进入 catch {} 然后再进入 finally{}
//如果没异常 直接进入 finally{}
//Try结束
}
catch (SqlException ex)
{
//catch 有异常才会进入我这里
}
finally
{
//无论如何都会进入我这里,这里适合做一些释放资源的事情
//这里可以舍去不用
}
Try块中包含的代码通常需要执行一些操作:抛出异常需要从异常中恢复。异常恢复的代码应放在一个或多个catch块中。针对应用程序能从中安全恢复的每一种异常,都应创建一个catch块。一个try块至少要有一个catch块或 finally块。单独的try块没有意义。如果一个try块中执行多个可能抛出同一异常的操作,但这些操作有不同的恢复措施,那么对每一个操作都应放在一个单独的try块中。
Catch块是响应一个异常需要处理的代码,catch关键字后的圆括号内的表达式称为捕捉类型(catch type)。在C#中,必须将捕捉类型指定为System.Exception或它的派生类型。没有捕捉类型的catch块将捕捉剩余的所有异常。多个 Catch块的顺序应将派生程度最大的类型放在最前面,最后放System.Excepton或没有捕捉类型的catch块。如果顺序错误会导致编译错 误。
如果在try块中抛出一个异常,CLR将搜索捕捉类型与异常类型相同的catch块,如果没有找到,CLR会调用栈的更高一层搜索与异常类型匹配的捕捉类型,如果到了栈的顶部还未找到,就会发生一个未处理异常。一旦找到一个匹配的catch块,所有内层的finally块会被执行;如果没有找到,内层的 finally块是不会执行的,这一点要特别注意。接着执行匹配catch块内容,最后是该catch块对应的finally块(如果有的话)。
对于匹配的catch块,我们通常的处理有3种:
1、重新抛出相同的异常,向上一层栈通知该异常的发生。
2、抛出一个不同的异常,向上一层栈提供更丰富的异常信息。
3、让线程从catch块的底部退出。(表示已处理这个异常,不会发生新的异常)
可以通过向AppDomain的FirstChanceException事件登记,只要在这个AppDomain内发生的异常,它就会收到通知。
Finally块的代码是保证会执行的代码。通常,finally块的代码执行try块中要求资源清理的操作。
Finally的用法:
try
{
//需要执行的代码放在这里
}
catch (InvalidOperationException)
{
//从InvalidOperationException恢复的代码放在这里
}
catch (IOException)
{
//从IOException恢复的代码放在这里
}
catch
{
//从除上面的异常外的其他异常恢复的代码放在这里
//???
//捕捉到任何异常,通常要重新抛出异常。
throw;
}
finally
{
//这里的代码总是执行,对始于try块的任何操作进行清理
}
// 如果try块没有异常,或异常被捕获后没有抛出,就执行这里的代码
举个例子:
FileStream fs = null;
try {
fs = new FileStream(pathName, FileMode.Open);
//处理文件的数据
}
catch (IOException) {
//在这里添加从IOException恢复的代码
}
finally {
//确保文件关闭
if (fs != null)
fs.Close();
}
这就是finally的语法和用法。
以上就是学习异常处理的时候的心得和体会。 |