捕获异常

前面主要说了关于异常的一些基础和理论知识,没有进入到正真的异常案例,这一讲通过几个案例来描述一下异常的捕获和处理.

案例代码:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace 异常处理

{

class Program

{

int result;

Program()

{

result = 0;

}

public void DisPlay(int a, int b)

{

try//这个话可能有问题

{

result = a / b;

}

catch (DivideByZeroException e) //不知道这个异常代表什么自己去查,有过那句话真的有问题,我就得治它

{

Console.WriteLine("Exception caught: {0}", e);

}

finally//不管如何,下面这句话我必须得输出

{

Console.WriteLine("Result: {0}", result);

}

}

static void Main(string[] args)

{

Program p = new Program();

p.DisPlay(25, 0);

Console.ReadKey();

}

}

}

别和我说你看不懂,唯一看不懂得地方就是哪一点try-catch语句的地方,我都注释好了(你试试没有try-catch语句会咋样?===>如果没有try,程序会终止)

简单说点其他小内容:

try ... catch 的目的是解决程序在出现错误时无法继续执行下去的问题。

try不一定只能和catch 配对,也可以try{}finally{}这样的形式,这不是没有意义,因为这样可以保证即使发生了异常,finally里面的代码一定会被执行。有时候,这个还是非常有用的。 比如可以用来释放一些自己占用的资源,然后让调用者处理异常。

对异常的捕获由三个部分组成:

try { //执行的代码,其中可能有异常。一旦发现异常,则立即跳到catch执行。否则不会执行catch里面的内容 } catch { //除非try里面执行代码发生了异常,否则这里的代码不会执行 } finally { //不管什么情况都会执行,包括try catch 里面用了return ,可以理解为只要执行了try或者catch,就一定会执行 finally }

Try语句

Catch语句

Finally语句

try -- 意思是 “试一试” 
catch --  意思是 “抓”,抓一抓。 
没有错,就抓不到错。有错才能抓到并处理。

一个try可以跟任意个catch(个数没有限制),主要是看有多少个异常类型,包括自定义的,Eeception是个类, 申明一个ex的Eeception对象,这个ex里面包含了当前发生在捕捉到的try块的所有异常信息,如ex.Message最常用的 (try块的详细异常信息),

ex的位置:只能在cath块 (异常处理块)
ex的作用:保存着系统捕获的异常;
为什么要用ex:  因为你不是神,并不能预测到你的程序会出什么错,所以就用
 MessageBox.Show(ex.Message);让系统提示你程序错在哪里,就可以顺藤摸瓜,逮到错误源从而解决他!

如果catch语句捕获了try语句不可能抛出的异常时,代码将不能通过,如果catch语句中使用如下方式:catch( Exception  e ){ }将在任何情况下,编译都能通过。

•try{    DataConnection.Open();    DataCommand.ExecuteReader();    ...    return;}finally{    DataConnection.Close();}

无论是否抛出异常,也无论在catch 中从什么地方return返回,finally语句块总是会执行,这样你有机会调用Close来关闭数据库连接(即使未打开或打开失败,关闭操作永远是可以执行的),以便于释放已经产生的连接,释放资源。
另外说明,return是可以放在try语句块中的。但不管在什么时机返回,在返回前,finally将会执行。

throw(不止throws)的作用是当代码执行到此处时认为的让程序出错,出错原因是你指定的内容
catch的作用是try包含的内容运行出错时,catch扑捉到try里面出错的原因,至于对于这个错误你怎么操作就放在catch里,你可以把错误写日志,messagebox输出等等

备注:throw是语句,抛出一个异常 ; throws是方法抛出一个异常;

throw语法: throw <异常对象>

(C#中是没有throws的,Java里有!别搞错了)throws语法 : [修饰符] <返回值类型> <方法名>([参数列表]) [throws <异常类>]

其中:异常类可以声明多个,用逗号分隔.

上面的那个案例,你试试经catch语句里的内容换成以下内容?

throw e;(应该会程序终止)

也可以换成这样:

throw new Exception("出错啦!", e);//这个时候也会终止程序,你注意看终止信息!!!

注意在捕获并抛出异常时应使用 throw new Exception("出错啦!", ex); 方式,则可获得异常的具体位置。

当在VS调试或者DEBUG模式下运行程序成都可获得异常发生的具体位置。

但当在独立运行的RELEASE模式下时,异常只会记录最初的调用位置。

当执行目录不包含 *.pdb 文件时,异常信息中不会包含代码及行号信息。

最后以一个案例结束异常捕获的部分:

class Program

{

static void Main(string[] args)

{

string userInput;

while (true)

{

try

{

Console.WriteLine("请输入0到5之间的任意一个数字: ");

userInput = Console.ReadLine();

if (userInput == "")

{

//当用户输入""时,跳出try和while但是仍然执行finally

break;

}

int index = Convert.ToInt32(userInput);

if (index < 0 || index > 5)

{

//抛出异常

//可使用System.Exception类,但是该类是个基本类,,没有包含特定错误信息

//此处可用派生类IndexOutRangeException

throw new IndexOutOfRangeException("请你看看要求好不好,你输入的是: " + userInput);

}

Console.WriteLine("你输入了:" + index);

}

//传递给catch块的参数只能用于该catch块,因此后续catch块仍然可用同名参数ex

catch (IndexOutOfRangeException ex)

{

Console.WriteLine("异常了: " + ex.Message);

}

/*

* 如果没有前面catch块中捕获的异常类,这个也能处理IndexOutOfRangeException

* 计算机只执行它在catchh块列表中找到的第一个合适的catch块

* 基类的一个引用可一直想派生于他的所有类实例

* 因此,最上面的catch块应用于最特殊的异常情况,最后的是一般的catch块

*

*/

catch (Exception ex)

{

Console.WriteLine("抛出异常: " + ex.Message);

}

/*

* 最一般的catch块(不带参数),用于处理其他没用C#编写的代码抛出的异常

* C#中只有派生于System.Exception类的实例才能作为一场抛出,其他语言没这个限制

* 此catch块同样捕获全部异常,只是不知异常的详细信息

*/

catch

{

//因为我们不知道这个异常表示什么类

Console.WriteLine("不知道什么异常,你自己猜去把.");

}

//无论执行try,catch最后都执行finally块

finally

{

Console.WriteLine("不管咋样,我都得执行,哥就是牛X");

}

/* 没有处理异常时发生的情况

* 生成一个异常后,代码中没有catch块能处理这异常,由.NET运行库捕获

* .NET运行库把整个程序放在另一个更大的try块中,用一个catch处理捕获所有异常

*/

}

}

}

注意:一般编写一个可执行程序,硬不货异常,编写一个库,最好不要补货,要家丁调用代码可以处理.

 

最新文章

  1. SignalR入门之持久性连接
  2. Soldier and Bananas
  3. CodeForces 702B Powers of Two (暴力,优化)
  4. 启动MYSQL密码审计插件
  5. UVa10653.Prince and Princess
  6. ios 软键盘顶起这个页面
  7. 为ubuntu添加右键打开终端效果
  8. Eclipse中pydev开发,python重载__init__报错,是可以正常执行
  9. IDEA远程调试监控端口
  10. 13树莓派手动安装Home Assistant
  11. loadrunner&#160;脚本优化-检查点设置
  12. Matplotlib学习---用seaborn画矩阵图(pair plot)
  13. Python的深copy和浅copy
  14. Netty重要概念介绍
  15. Vim 插键及配置
  16. 常见HTTP状态码(200、301、302、500等)解说
  17. Nexus 7更换NFC控制器,导致不再支持读取Mifare Classic NFC 1k Tags
  18. sql返回行id
  19. jQuery Grid入门指南
  20. Linux上添加新硬盘的实例介绍

热门文章

  1. 一台电脑,两个及多个git账号配置
  2. Luogu P4944 【PION贪吃蛇】
  3. oracle查询出来的时间吸附为每5min
  4. Hibernate之开门见山
  5. java 泛型 ? 和 T的区别
  6. 矩阵优化dp
  7. 如何删除jsPlumb连接
  8. BZOJ4974 八月月赛 Problem D 字符串大师 KMP
  9. 统计难题 HDU1251
  10. unity 之 no cameras rendering