服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - 学会使用C#异常

学会使用C#异常

2021-12-16 13:08反骨仔(二五仔) C#

在C#中,程序中在运行时出现的错误,会不断在程序中进行传播,这种机制称为“异常”。 异常通常由错误的代码引发,并由能够更正错误的代码进行catch。本文将对C#异常简要分析说明,下面就跟着小编一起来看下吧

在 C# 中,程序中在运行时出现的错误,会不断在程序中进行传播,这种机制称为“异常”。异常通常由错误的代码引发,并由能够更正错误的代码进行 catch。异常可由 .NET 的 CLR 或由程序中的代码引发。一旦引发了异常,这个异常将会在调用堆栈中一直向上进行传播,直到寻找到跟它匹配的 catch 语句。没有 catch 的异常会由系统提供的默认的异常处理程序进行处理,也就是你经常看到的一个突然造成调试中断并显示异常信息的对话框。

所有的异常,它们都是从 Exception 派生出来的。这些异常的类型,都会包含详细描述异常的属性。在这里我将自定义了一个新的异常类,其实也可以自定义配置异常的属性(这是可选的),然后我使用 throw 关键字显示引发该对象(即异常)。

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

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

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

学会使用C#异常

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

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

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

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

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

学会使用C#异常

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

原文链接:http://www.cnblogs.com/liqingwen/p/6193534.html

如果 WriteByte(0)(第9行) 引发了异常,那么在没有调用 fs.Close() 的情况下,你在第二个 try 块中尝试重新 OpenWrit() 的代码就会失败,因为此时文件会保持锁定状态。 假如你取消注释,由于会执行 finally 块(即使已引发异常),使得可以正确地关闭文件,从而避免再次引发异常。

如果在引发异常之后没有在调用堆栈上找到相匹配的 catch 块,则会可能会出现下面的情况:

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

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持服务器之家!

延伸 · 阅读

精彩推荐
  • C#聊一聊C#接口问题 新手速来围观

    聊一聊C#接口问题 新手速来围观

    聊一聊C#接口问题,新手速来围观,一个通俗易懂的例子帮助大家更好的理解C#接口问题,感兴趣的小伙伴们可以参考一下...

    zenkey7072021-12-03
  • C#C#基础之泛型

    C#基础之泛型

    泛型是 2.0 版 C# 语言和公共语言运行库 (CLR) 中的一个新功能。接下来通过本文给大家介绍c#基础之泛型,感兴趣的朋友一起学习吧...

    方小白7732021-12-03
  • C#c#学习之30分钟学会XAML

    c#学习之30分钟学会XAML

    一个界面程序的核心,无疑就是界面和后台代码,而xaml就是微软为构建应用程序界面而创建的一种描述性语言,也就是说,这东西是搞界面的...

    C#教程网8812021-12-10
  • C#C#实现的文件操作封装类完整实例【删除,移动,复制,重命名】

    C#实现的文件操作封装类完整实例【删除,移动,复制,重命名】

    这篇文章主要介绍了C#实现的文件操作封装类,结合完整实例形式分析了C#封装文件的删除,移动,复制,重命名等操作相关实现技巧,需要的朋友可以参考下...

    Rising_Sun3892021-12-28
  • C#C#直线的最小二乘法线性回归运算实例

    C#直线的最小二乘法线性回归运算实例

    这篇文章主要介绍了C#直线的最小二乘法线性回归运算方法,实例分析了给定一组点,用最小二乘法进行线性回归运算的实现技巧,具有一定参考借鉴价值,需要...

    北风其凉8912021-10-18
  • C#浅谈C# winForm 窗体闪烁的问题

    浅谈C# winForm 窗体闪烁的问题

    下面小编就为大家带来一篇浅谈C# winForm 窗体闪烁的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    C#教程网7962021-12-21
  • C#C# 后台处理图片的几种方法

    C# 后台处理图片的几种方法

    本篇文章主要介绍了C# 后台处理图片的几种方法,非常具有实用价值,需要的朋友可以参考下。...

    IT小伙儿10162021-12-08
  • C#Unity3D UGUI实现缩放循环拖动卡牌展示效果

    Unity3D UGUI实现缩放循环拖动卡牌展示效果

    这篇文章主要为大家详细介绍了Unity3D UGUI实现缩放循环拖动展示卡牌效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参...

    诗远3662022-03-11