[C#] C# 知识回顾 - 学会使用异常
学会使用异常
异常:指的是我们写的程序在运行时出现了错误,并且它会不断的蔓延、传播和扩散,有点像病毒一样。
异常通常由错误的代码引发,可能是用户的错误输入,可能是一方没有按照约定来传输格式,也可能是数据传输的过程中被篡改。我们会对自己认为有可能报错的代码进行 catch ,这称为捕获异常。
一旦引发了异常,这个异常将会在调用堆栈中一直向上进行传播,直到寻找到跟它匹配的 catch
语句。没有 catch 的异常会由系统提供的默认的异常处理程序进行处理,也就是你经常看到的一个突然造成调试中断并显示异常信息的对话框。
所有的异常,它都是从 Exception 派生出来的,他们都包含了详细的异常描述属性。在这里我将自定义了一个新的异常类,然后使用 throw
关键字显式引发该对象(即异常)。
/// <summary>
/// 定义新异常
/// </summary>
class MyException : Exception
{
public MyException(string msg) { }
} /// <summary>
/// 抛出新定义的异常
/// </summary>
static void ThrowMyExcetion()
{
throw new MyException("Sorry, this is test!");
}
在引发异常之后,CLR 运行时程序会检查当前语句确定它是否包含在 try
块中。 如果是的话,就会检查与该 try
块相关联的所有 catch
块,来确定它们是否能够 catch 该异常。如果该 catch
块的类型与异常或它的基类的相同(或匹配),则该 catch
块就能够捕获并处理。
static void Main(string[] args)
{
try
{
ThrowMyExcetion(); //直接调用抛出异常的方法
}
catch (MyException e)
{
Console.WriteLine(e);
} Console.Read();
}
如果引发异常的语句不在 try
块中,或者包含该语句的 try
块没有匹配的 catch
块,CLR 运行时将检查调用方法中是否有合适 try
语句和 catch
块。 运行时将在调用堆栈中继续往上搜索兼容(或匹配)的 catch
块。在找到并执行 catch
块之后,控制权将传递给 catch
块之后的下一个语句。
一个 try
语句可能包含多个 catch
块。 将执行第一个能够处理该异常的 catch
语句;任何后续的 catch
语句都将被忽略。 因此,在任何情况下都应该按照从最具体(或者派生程度最高)到最不具体这一顺序排列 catch 块。 例如:
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
块可能遗留下的任何模糊状态,或者释放任何外部资源(例如图形句柄、数据库连接或文件流),而无需等待运行时中的垃圾回收器终结这些对象。 例如:
static void Main(string[] args)
{
FileStream fs = null;
FileInfo fi = new FileInfo(@"小二和小三的故事.txt"); try
{
fs = fi.OpenWrite();
fs.WriteByte();
}
finally
{
//记住哦,如果你忘记 close,将会引发 IO 异常!
//if (fs != null)
//{
// fs.Close();
//}
} try
{
fs = fi.OpenWrite();
fs.WriteByte();
Console.WriteLine("OK!");
}
catch (IOException e)
{
Console.WriteLine("Fail!");
} Console.Read();
}
“Fail!”,这是因为上面注释了需要关闭文件流的语句,你可以尝试下去掉注释看看结果,记住哦,IO 操作都应该在结束时释放资源。
如果 WriteByte(0)(第9行)
引发了异常,那么在没有调用 fs.Close()
的情况下,你在第二个 try
块中尝试重新 OpenWrit() 的代码就会失败,因为此时文件会保持锁定状态。 假如你取消注释,由于会执行 finally
块(即使已引发异常),使得可以正确地关闭文件,从而避免再次引发异常。
如果在引发异常之后没有在调用堆栈上找到相匹配的 catch
块,则:
如果异常出现在析构函数中,则中止该析构函数并调用基类的析构函数(如果有)。
如果调用堆栈包含静态构造函数或静态字段初始值设定项,则会引发 TypeInitializationException,并将原始异常分配给新异常的 InnerException 属性。
如果到达线程的开头,将会终止线程。
C# 基础回顾系列
《C# 知识回顾 - 委托 delegate》、《C# 知识回顾 - 委托 delegate (续)》
《C# 知识回顾 - 事件入门》、《C# 知识回顾 - Event 事件》
《string 与 String,大 S 与小 S 之间没有什么不可言说的秘密》
【博主】反骨仔
【出处】http://www.cnblogs.com/liqingwen/p/6193534.html
【参考】https://docs.microsoft.com/zh-cn/dotnet/articles/csharp/programming-guide/exceptions/using-exceptions
【参考】微软官方文档
[C#] C# 知识回顾 - 学会使用异常的更多相关文章
- [C#] C# 知识回顾 - 学会处理异常
学会处理异常 你可以使用 try 块来对你觉得可能会出现异常的代码进行分区. 其中,与之关联的 catch 块可用于处理任何异常情况. 一个包含代码的 finally 块,无论 try 块中是否在运行 ...
- [C#] C# 知识回顾 - 你真的懂异常(Exception)吗?
你真的懂异常(Exception)吗? 目录 异常介绍 异常的特点 怎样使用异常 处理异常的 try-catch-finally 捕获异常的 Catch 块 释放资源的 Finally 块 一.异常介 ...
- [C#] C# 知识回顾 - 异常介绍
异常介绍 我们平时在写程序时,无意中(或技术不够),而导致程序运行时出现意外(或异常),对于这个问题, C# 有专门的异常处理程序. 异常处理所涉及到的关键字有 try.catch 和 finally ...
- [C#] C# 知识回顾 - 序列化
C# 知识回顾 - 序列化 [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902005.html 目录 序列化的含义 通过序列化保存对象数据 众 ...
- java基础知识回顾之---java String final类普通方法
辞职了,最近一段时间在找工作,把在大二的时候学习java基础知识回顾下,拿出来跟大家分享,如果有问题,欢迎大家的指正. /* * 按照面向对象的思想对字符串进行功能分类. * ...
- C# 知识回顾 - 装箱与拆箱
装箱与拆箱 目录 生活中的装箱与拆箱 C# 的装箱与拆箱 值类型和引用类型 装箱 拆箱 生活中的装箱与拆箱 我们习惯了在网上购物,这次你想买本编程书 -- <C 语言从入门到放弃> ...
- Java基础知识回顾之七 ----- 总结篇
前言 在之前Java基础知识回顾中,我们回顾了基础数据类型.修饰符和String.三大特性.集合.多线程和IO.本篇文章则对之前学过的知识进行总结.除了简单的复习之外,还会增加一些相应的理解. 基础数 ...
- [C#] C# 知识回顾 - 装箱与拆箱
装箱与拆箱 目录 生活中的装箱与拆箱 C# 的装箱与拆箱 值类型和引用类型 装箱 拆箱 读者见解 生活中的装箱与拆箱 我们习惯了在网上购物,这次你想买本编程书 -- <C 语言从入门到放弃 ...
- [C#] C# 知识回顾 - Lambda
C# 知识回顾 - Lambda 序 它是第十一个希腊字母,一个拥有失意.无奈.孤独.低调等含义的流行符号,也指示一款称为“半条命”的游戏. 不过,这次我所讲的是 C# 中的 Lambda. 目录 L ...
随机推荐
- Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part1:准备工作
Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part1:准备工作 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 1.实施前准备工作 1.1 服务器安装操 ...
- 札记:android手势识别,MotionEvent
摘要 本文是手势识别输入事件处理的完整学习记录.内容包括输入事件InputEvent响应方式,触摸事件MotionEvent的概念和使用,触摸事件的动作分类.多点触摸.根据案例和API分析了触摸手势T ...
- 【CSS进阶】伪元素的妙用--单标签之美
最近在研读 <CSS SECRET>(CSS揭秘)这本大作,对 CSS 有了更深层次的理解,折腾了下面这个项目: CSS3奇思妙想 -- Demo (请用 Chrome 浏览器打开,非常值 ...
- 在docker中运行ASP.NET Core Web API应用程序(附AWS Windows Server 2016 widt Container实战案例)
环境准备 1.亚马逊EC2 Windows Server 2016 with Container 2.Visual Studio 2015 Enterprise(Profresianal要装Updat ...
- Redis/HBase/Tair比较
KV系统对比表 对比维度 Redis Redis Cluster Medis Hbase Tair 访问模式 支持Value大小 理论上不超过1GB(建议不超过1MB) 理论上可配置(默认配置1 ...
- 启用 Open vSwitch - 每天5分钟玩转 OpenStack(127)
Linux Bridge 和 Open vSwitch 是目前 OpenStack 中使用最广泛的两种虚机交换机技术. 前面各章节我们已经学习了如何用 Linux Bridge 作为 ML2 mech ...
- Xamarin与Visual stuido2015离线安装包分享
最近看见大伙留言才知道国内安装Xamarin开发原来这么艰辛啊! 第一:网速不快 第二:Android SDK下载受限 等等... 鉴于这些原因,特写下这篇文章以及分享打包好的离线包以帮助大家尽快体验 ...
- UWP开发必备以及常用知识点总结
一直在学UWP,一直在写Code,自己到达了什么水平?还有多少东西需要学习才能独挡一面?我想对刚接触UWP的开发者都有这种困惑,偶尔停下来总结分析一下还是很有收获的! 以下内容是自己开发中经常遇到的一 ...
- ASP.NET Core 中文文档目录
翻译计划 五月中旬 .NET Core RC2 如期发布,我们遂决定翻译 ASP.NET Core 文档.我们在 何镇汐先生. 悲梦先生. 张仁建先生和 雷欧纳德先生的群中发布了翻译计划招募信息,并召 ...
- Android Studio快捷键
一.android studio 默认快捷键 刚开始接触一款开发软件,想必很想了解它的快捷方式,这会对你的编程起到很好的帮助,提高工作效率,接下来给你介绍下Android Studio一些常用的快 ...