一、Exception:异常类
.NET Framework 类库中的所有异常都派生于 Exception 类,异常包括系统异常和应用异常。
默认所有系统异常派生于 System.SystemException,所有的应用程序异常派生于 System.ApplicationException。
系统异常包括 OutOfMemoryException、IOException、NullReferenceException。
常用的异常类如下图所示。
常用的系统异常类如下表所示。
异常类 | 说明 |
---|---|
System.OutOfMemoryException | 用 new 分配内存失败 |
System.StackOverflowException | 递归过多、过深 |
System.NullReferenceException | 对象为空 |
Syetem.IndexOutOfRangeException | 数组越界 |
System.ArithmaticException | 算术操作异常的基类 |
System.DivideByZeroException | 除零错误 |
二、try catch finally:异常处理
在 C# 语言中异常与异常处理语句包括三种形式,即 try catch、try finally、try catch finally。
在上述三种异常处理的形式中所用到关键字其含义如下:
try:用于检查发生的异常,并帮助发送任何可能的异常。
catch:以控制权更大的方式处理错误,可以有多个 catch 子句。
finally:无论是否引发了异常,finally 的代码块都将被执行。
1. try catch
在 try 语句中放置可能出现异常的语句,而在 catch 语句中放置异常时处理异常的语句,通常在 catch 语句中输出异常信息或者发送邮件给开发人员等。
下面通过实例来演示 try catch 的应用。
另外,在处理异常时,catch 语句是允许多次使用的,相当于多分支的 if 语句,仅能执行其中一个分支。
1)例
在文本框中输入一个整数,并判断其是否大于 100。
步骤如下:
I.首先是创建窗体并布局。
这里是1个Label控件、1个TextBox控件、1个Button控件。
修改Text属性值。
根据题目要求,如果在文本框中输入的是一个字符串或者浮点数,就会出现类型转换错误,如下图所示。
private void button1_Click(object sender, EventArgs e) { string str = textBox1.Text; int num = int.Parse(str); MessageBox.Show("您输入的数字是:" + num); }
运行后,会报错。
所以,需要通过使用try--catch语句进行处理。
双击“确定”按钮控件,生成单击事件。
private void button1_Click(object sender, EventArgs e) { //获取文本框中的值 string str = textBox1.Text; //将字符串装换为整数 try { int num = int.Parse(str); MessageBox.Show("您输入的数字是:" + num); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
分析:
首先要获取表单TextBox控件中的值。
因为默认是字符串,所以需要用string数据类型进行定义。
然后放进try中进行判断,如果输入的不是数值int类型,就会报错,从而执行catch里面的内容。
这里的try和catch,有点类似if-else语句。
在try语句中进行判断,如果出现异常就执行catch语句里的内容。否则不用执行。
运行结果:
2)例
使用多个 catch 语句对程序做异常处理。
从控制台输入 5 个数存入整数数组中,首先判断输入的值是否为数值,再判断数组元素是否越界。
根据题目要求,创建控制台应用程序完成该实例,具体的代码如下。
这里使用命令行的方式进行测试。
不过我尝试了一下,采用.NET Core的方式使用。
虽然经过了一定的修改,但基础代码看来还是一样。
using System;namespace ConsoleApp1{ class Program { static void Main(string[] args) { //定义存放5个整数的数组 int[] a = new int[5]; try { for (int i = 0; i < a.Length; i++) { a[i] = int.Parse(Console.ReadLine()); } for (int i = 0; i < a.Length; i++) { Console.Write(a[i] + " "); } } catch (FormatException f) { Console.WriteLine("输入的数字格式不正确!"); } catch (OverflowException o) { Console.WriteLine("输入的值已经超出 int 类型的最大值!"); } catch (IndexOutOfRangeException r) { Console.WriteLine("数组越界异常!"); } } }}
分析:
这里的目的是手动输入5个数,然后存入数组中,并遍历输出到命令行中。
首先是定义了一个数组。
然后放进try语句中进行代码编辑。
也就是重复5次输入数字,然后依次输出这些数字。
因为都是重复,所以就使用了循环。
再然后就是进行catch语句的判断。
至于里面的参数,是系统集成的一些固定参数。
只要try语句中出现异常,就会返回一个参数。
而这个参数就会进行设置参数的对接,并且返回输出的提示。
FormatException:输入的数字格式不正确!
OverflowException o:输入的值已经超出 int 类型的最大值!
IndexOutOfRangeException r:"数组越界异常!"
运行结果:
2.try finally
在 try finally 形式中没有单独对出现异常时处理的代码,finally 语句是无论 try 中的语句是否正确执行都会执行的语句。
通常在 finally 中编写的代码是关闭流、关闭数据库连接等操作,以免造成资源的浪费。
下面通过实例来演示 try finally 形式的应用。
1)验证 finally 语句的使用。
总之就是这个页面布局。
然后双击“确定”按钮控件,代码如下:
private void button1_Click(object sender, EventArgs e) { //获取文本框中的值 string str = textBox1.Text; //将字符串装换为整数 try { int num = int.Parse(str); MessageBox.Show("您输入的数字是:" + num); } finally { MessageBox.Show("finally 语句"); } }
分析:
其实也就改了11~14行。
把catch换成了finally,并且一样的消息框提示。
而这里的finally,跟catch不一样。
finally无论try语句是否存不存在报错异常,都会输出finally语句中的内容。
运行结果:
首先会弹出正确提示,然后才会再提示finally语句中的内容。
如果输入的是异常字符串。
就会报错,因为没有进行catch语句处理。
而从下面的未经处理的异常,
System.FormatException:“输入字符串的格式不正确。”
就可以确定是catch(FormatException f){},所执行的内容。
如果catch{}每次参数参与,那就是包含所有报错方式。
2)例
从文本框中输入当天的天气情况,并将其写入文件中,无论写入是否成功都将文件流关闭。
根据题目要求,使用 Windows 应用程序完成该实例,界面设计如下图所示。
步骤如下:
先创建窗体并布局。
总之就是4个Label标签控件、4个TextBox表单控件、2个Button按钮控件。
双击“确定”按钮控件,生成单击事件。
并且实现单击“确认”按钮后,将界面的文本框中的信息写入名为 weather.txt 的文本文件中, 代码如下:
private void button1_Click_1(object sender, EventArgs e) { //获取文本框 string city = textBox1.Text; string msg = textBox2.Text; string min = textBox3.Text; string max = textBox4.Text; //将文本框中的内容组成一个字符串 string message = city + ":" + msg + ":" + min + "~" + max; //定义文件路径 string path = "D:\\code\\weather.txt"; FileStream fileStream = null; try { //创建fileSteam类的对象 fileStream = new FileStream(path, FileMode.OpenOrCreate); //将字符串转换成字节数组 byte[] bytes = Encoding.UTF8.GetBytes(message); //向文件中写入字节数组 fileStream.Write(bytes, 0, bytes.Length); //刷新缓冲区 fileStream.Flush(); //弹出录入成功的消息框 MessageBox.Show("天气信息录入成功!"); } finally { if (fileStream != null) { //关闭流 fileStream.Close(); } } }
分析:
首先需要导入using System.IO;
因为涉及到文件输入和输出。
然后就是编辑“确定”按钮控件的事件。(这里也就设计“确定”按钮一个功能。)
首先是获取4个输入框表单里的内容。
然后将它们拼接成一个字符串变量。
再然后确定一个所存储的文件路径。
再定义一个FileSteam类的全局变量。
然后进入try语句块中。
因为这部分有可能出现错误,所以放进try语句块中。
先定义找到文件,将文件打开以便进行操作。
然后见message字符串变量进行转码变成字节数组。
再然后是往文件里写入,刷新,录入提示。
然后通过finally语句,进行最终的关闭文件。
运行结果:
然后你就看到文件中有了内容。
3. try catch finally
try catch finally 形式语句是使用最多的一种异常处理语句。
在出现异常时能提供相应的异常处理,并能在 finally 语句中保证资源的回收。
下面通过实例来演示 try catch finally 语句的应用。
1)例
使用 try catch finally 形式完成上面案例的题目要求。
首先还是这个布局。
然后是“确定”按钮的单击事件代码:
private void button1_Click(object sender, EventArgs e) { //获取文本框 string city = textBox1.Text; string msg = textBox2.Text; string min = textBox3.Text; string max = textBox4.Text; //将文本框中的内容组成一个字符串 string message = city + ":" + msg + ":" + min + "~" + max; //定义文件路径 string path = "D:\\code\\weather.txt"; FileStream fileStream = null; try { //创建fileSteam类的对象 fileStream = new FileStream(path, FileMode.OpenOrCreate); //将字符串转换成字节数组 byte[] bytes = Encoding.UTF8.GetBytes(message); //向文件中写入字节数组 fileStream.Write(bytes, 0, bytes.Length); //刷新缓冲区 fileStream.Flush(); //弹出录入成功的消息框 MessageBox.Show("天气信息录入成功!"); } catch (Exception ex) { MessageBox.Show("出现错误!" + ex.Message); } finally { if (fileStream != null) { //关闭流 fileStream.Close(); } } }
分析:
首先是获取表单里的数据,然后将它们组合起来用于文件的输入。
然后定义文件地址,创建文件的输入,并且进行文件的输入流程操作。
如果输入有误,就进行报错提示。
如果一切正常,也就执行关闭流操作。
运行结果:
运行该窗体,效果与实例 4 所示的一样,但是当程序出现错误时会弹出 catch 语句中的提示消息。