[C#] 学会使用异常(整理中)

学会使用异常

  在 C# 中,程序中的运行时错误通过使用一种称为“异常”的机制在程序中传播。 异常由错误的代码引发,并由能够更正错误的代码进行捕捉。 异常可由 .NET 的公共语言运行时 (CLR) 或由程序中的代码引发。 一旦引发了一个异常,这个异常就会在调用堆栈中向上传播,直到找到针对它的 catch 语句。未捕获的异常由系统提供的通用异常处理程序处理,也就是你经常看到的一个对话框。

  异常由从 Exception 派生的类进行表示。此类标识异常的类型,并包含详细描述异常的属性。这里演示自定义一个新的异常类,并可以由你自定义配置异常的属性(可选),然后使用 throw 关键字引发该对象(即异常)。

 1         /// <summary>
 2         /// 定义新异常
 3         /// </summary>
 4         class MyException : Exception
 5         {
 6             public MyException(string msg) { }
 7         }
 8
 9         /// <summary>
10         /// 抛出新定义的异常
11         /// </summary>
12         static void ThrowMyExcetion()
13         {
14             throw new MyException("Sorry, this is test!");
15         }

  

  在引发异常之后,运行时检查当前语句以确定它是否在 try 块中。 如果是,则检查与该 try 块关联的任何 catch 块,以确定它们是否能够捕获该异常。 Catch 块通常会指定异常类型;如果该 catch 块的类型与异常或异常的基类的类型相同(或匹配),则该 catch 块就能够处理。

 1         static void Main(string[] args)
 2         {
 3             try
 4             {
 5                 ThrowMyExcetion();  //直接调用抛出异常的方法
 6             }
 7             catch (MyException e)
 8             {
 9                 Console.WriteLine(e);
10             }
11
12             Console.Read();
13         }

  如果引发异常的语句不在 try 块中,或者包含该语句的 try 块没有匹配的 catch 块,运行时将检查调用方法中是否有 try 语句和 catch 块。 运行时将在调用堆栈中向上继续搜索兼容的 catch 块。在找到并执行 catch 块之后,控制权将传递给 catch 块之后的下一个语句。

  一个 try 语句可能包含多个 catch 块。 将执行第一个能够处理该异常的 catch 语句;任何后续的 catch 语句都将被忽略,即使它们是兼容的也如此。 因此,在任何情况下都应该按照从最具体(或者派生程度最高)到最不具体这一顺序排列 catch 块。 例如:

 1         static void Main(string[] args)
 2         {
 3             StreamWriter sw = null;
 4
 5             try
 6             {
 7                 sw = new StreamWriter(@"C:\book\小二和小三的故事.txt");
 8                 sw.Write("You are 250.");
 9             }
10             catch (FileNotFoundException e)
11             {
12                 //将具体的异常放在第一位
13                 Console.WriteLine(e);
14             }
15             catch (IOException e)
16             {
17                 //将并不具体的放在相对后面的位置
18                 Console.WriteLine(e);
19             }
20             catch (Exception e)
21             {
22                 Console.WriteLine(e);
23             }
24             finally
25             {
26                 if (sw != null)
27                 {
28                     sw.Close();
29                 }
30             }
31
32             Console.Read();
33         }

  执行 catch 块之前,运行时会检查 finally 块。 Finally 块使程序员能够清除中止的 try 块可能遗留下的任何模糊状态,或者释放任何外部资源(例如图形句柄、数据库连接或文件流),而无需等待运行时中的垃圾回收器终结这些对象。 例如:

 1         static void Main(string[] args)
 2         {
 3             FileStream fs = null;
 4             FileInfo fi = new FileInfo(@"小二和小三的故事.txt");
 5
 6             try
 7             {
 8                 fs = fi.OpenWrite();
 9                 fs.WriteByte(0);
10             }
11             finally
12             {
13                 //记住哦,如果你忘记 close,将会引发 IO 异常!
14                 //if (fs != null)
15                 //{
16                 //    fs.Close();
17                 //}
18             }
19
20             try
21             {
22                 fs = fi.OpenWrite();
23                 fs.WriteByte(1);
24                 Console.WriteLine("OK!");
25             }
26             catch (IOException e)
27             {
28                 Console.WriteLine("Fail!");
29             }
30
31             Console.Read();
32         }

  “Fail!”,这是因为上面注释了需要关闭文件流的语句,你可以尝试下去掉注释看看结果,记住哦,IO 操作都应该在结束时释放资源。 

  如果 WriteByte() 引发了异常,那么在没有调用 fs.Close() 的情况下,第二个 try 块中尝试重新打开文件的代码就会失败,并且文件将保持锁定状态。 由于要执行 finally 块(即使已引发异常),前一示例中的 finally 块使得可以正确地关闭文件,从而帮助避免错误。

  如果在引发异常之后没有在调用堆栈上找到兼容的 catch 块,则会出现三种情况中的一种:

  • 如果异常出现在析构函数中,则中止该析构函数并调用基析构函数(如果有)。
  • 如果调用堆栈包含静态构造函数或静态字段初始值设定项,则引发一个 TypeInitializationException,并将原始异常分配给新异常的 InnerException 属性。
  • 如果到达线程的开头,则终止线程。


【博主】反骨仔

【出处】http://www.cnblogs.com/liqingwen/p/6193534.html

【参考】微软官方文档

时间: 2024-08-14 00:44:22

[C#] 学会使用异常(整理中)的相关文章

Java开发中常见异常整理

算术异常类:ArithmeticExecption 空指针异常类:NullPointerException 类型强制转换异常:ClassCastException 数组负下标异常:NegativeArrayException 数组下标越界异常:ArrayIndexOutOfBoundsException 违背安全原则异常:SecturityException 文件已结束异常:EOFException 文件未找到异常:FileNotFoundException 字符串转换为数字异常:NumberF

[C#] 学会处理异常

学会处理异常 C# 程序员可使用 try 块对可能受异常影响的代码进行分区. 关联的 catch 块用于处理任何结果异常. 一个包含代码的 finally 块,无论 try 块中是否引发异常(例如,释放在 try 块中分配的资源),这些代码都会运行. 一个 try 块需要一个或多个关联的 catch 块或一个 finally 块,或两者. 这里分别给出了一个 try-catch 语句,一个 try-finally 语句,和一个 try-catch-finally 语句. try-catch: 1

Java异常打印输出中常见方法的分析

Java异常是在Java应用中的警报器,在出现异常的情况下,可以帮助我们程序猿们快速定位问题的类型以及位置.但是一般在我们的项目中,由于经验阅历等多方面的原因,依然有若干的童鞋在代码中没有正确的使用异常打印方法,导致在项目的后台日志中,没有收到日志或者日志信息不完整等情况的发生,这些都给项目埋下了若干隐患.本文将深入分析在异常日志打印过程中的若干情况,并给出若干的使用建议. 1. Java异常Exception的结构分析 我们通常所说的Exception主要是继承于Throwable而来,可以参

OpenCV访问Mat对象中数据时发生异常---Mat中的数据访问

7.1和7.1.1由于越狱不成熟,半完美越狱后电脑上无法访问系统越狱目录,如var usr 等等. 今天有些意外地发现,可以在电脑上使用手机的越狱目录我手机 i4 7.1.1 联通 半完美越狱,没装Afc2Add,也没装Appsync 附上  --->我的半完美越狱过程 好了,下面直接正题 一.前提,必须安装ifile! 打开ifile,并转到 /var/mobile/media 目录下,然后点击右上角的 [ 编辑 ]如图: 二.点左下角的 + 号创建,如图: 三.点 [ 类型],选择[符号链接

找回VisualStudio异常设置中丢失的“用户未处理的(User-unhandled)”列

今天发现我的VisualStudio中的异常设置中"用户未处理的"列丢失了 虽然我很少设置这一项,但没了还是觉得怪怪的,网上搜了一下,在文章"USER-UNHANDLED" COLUMN IS MISSING IN VISUAL STUDIO'S DEBUG EXCEPTIONS WINDOW中找到了答案:在选项设置中将调试的"启用仅我的代码"一项选中即可. 现在就回到了熟悉的界面了.

WCF之常见异常整理(不断更新中...)

系统Win7   IIS7.5 异常1.找不到具有绑定 NetTcpBinding 的终结点的与方案 net.tcp 匹配的基址.注册的基址方案是 [http]. 产生原因:网站没有配置net.tcp协议,网站默认只有http协议 解决方案:打开IIS选择编辑网站下的绑定,配置net.tcp协议,具体操作可自行搜索. 疑问:网站正确配置了net.tcp协议,还报这个错误? 可能原因:端口不对,比如在IIS中配置的net.tcp协议的端口1000,可能在Visul Studio中 右键打开svc文

StringWriter/PrintWriter在Java输出异常信息中的作用

闲来无事,看看JUnit的源代码.刚刚开始看就发现一段有趣的代码: public String trace() { StringWriter stringWriter = new StringWriter(); PrintWriter writer = new PrintWriter(stringWriter); thrownException().printStackTrace(writer); StringBuffer buffer = stringWriter.getBuffer(); r

数据库异常sysservers中找不到服务器 源码下载

本文引用于:征途源码论坛(www.zhengtuwl.com)-----专注各类免费精品源码下载的平台 数据库异常:[DBNETLIB][ConnectionOpen (Connect()).]SQL Server 不存在或拒绝访问. 网狐架设很多人第一架设肯定要遇到这个问题,网上找教程,也没有提到这个的,这里我来写解决方法,免得再有人问我了!本站是不提供技术服务的,在QQ上问我问题我是直接忽略的,有问题发布到论坛,只要是我知道的我就一定帮助解决,不要再QQ上问我了!开始->所有程序->Mic

数据库异常整理:org.hibernate.QueryException: could not resolve property: “mStation”

最近用hibernate作数据库查询,结果遇到问题: org.hibernate.QueryException: could not resolve property: 'mStation'of  经过各个步骤检查,还是没找到方法. 在此,整理一下这个问题的导致可能原因: 一.排查HQL语句中的类字段,看是否是java类中的字段,不要是数据库中的字段: 二.排查各个字段是否与类中字段一致,绝大多数可能是由于字段不匹配导致的问题: 三.如果以上两部都检查没有问题,那么很可能就是JavaBean命名