C#异常处理
(PS个人看法:
其实我一直对这个异常机制不怎么重视,也是我不懂吧,有些想不明白,程序运行期间搞出个异常干什么,好像没什么作用,就给出个提示而已,在学C++的时候,我是这么想的。
实际也处理不了异常,最后程序依然是结束了,如果出现了异常,这个异常处理好像没起到任何作用。
至少在我看到的程序中,都是这样的。
在C++中,如果真的出现错误了,比如什么文件不存在,网络连接失败。从某些函数的返回值就可以判断。直接可以处理。。
异常try catch这个机制好像也参与不进来。
所以我就没怎么重视C++的异常。当然我知道它的存在就是有它的作用的。比如那个除零异常,它的重要性只是我没去深入了解,
没发现罢了。
但到了C#就不一样了,我很快就发现这个try catch的重要性,比如文件不存在的话,你不用try catch处理,程序就自动结束了。我晕。
没办法,学习一下这个异常处理吧)
其实这个try catch也蛮方便的,不像C++,如果打不开文件,要找原因的话,还要自己判断函数的返回值。以此找寻可能是什么原因。最后给出提示诸如:“文件不存在!”之类的。
但c# 的try catch,可以帮你找出原因。给出相关的提示。异常信息存在于Exception类里的Message属性成员中。
来看一个例子:
class Program
{
static void Main(string[] args)
{
int num = int.Parse(Console.ReadLine());
for (int i = 0; i < 10; i++)
{
Console.WriteLine("{0}", i);
}
}
}
上面这个程序,如果从控制台输入数字的话,则不会有什么问题,但如果输入字符串的话,就会产生异常,程序就结束了。后面的循环输出十个数的代码也不会被执行。其实也就是Parse引发的异常,转化不了字符串,如 int.Parse("aaaa");
但C++则不一样,如果输入的不是数字,函数就会返回零,我们可以通过这个函数的返回值来判断,是否正确输入。
如:int res=scanf("%d",&num); 如果输入的是字符串的话,res的值就是0。
上面的那个例子,产生了异常,那么我们就来捕捉异常和处理异常吧,增加这个程序的健壮性。
使用异常处理的例子:
class Program
{
static void Main(string[] args)
{
try
{
int num = int.Parse(Console.ReadLine());
}
catch (Exception e)
{
//简单的输出错误信息
Console.WriteLine(e.Message);
}
for (int i = 0; i < 10; i++)
{
Console.WriteLine("{0}", i);
}
}
}
在这个例子中,就算输入字符串,后面的代码也依然会被执行。在try里面的语句,表明是可能会引发异常的语句。而catch里面的语句,表明如果引发异常。这里面的语句就会被执行。
接着来看第二个例子,如果输入的是字符串,则提示用户重新输出。通过异常处理来实现。
class Program
{
static void Main(string[] args)
{
int num;
while (true)
{
try
{
num = int.Parse(Console.ReadLine());
}
catch (Exception e)
{
Console.WriteLine("输入错误,请重新输入!");
continue;
}
break;
}
for (int i = 0; i < 10; i++)
{
Console.WriteLine("{0}", i);
}
}
}
第三个,文件不存在的异常处理FileNotFoundException
先在D盘建立一个test.txt文件,内容为12345,看下例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace TestConls
{
class Program
{
static void Main(string[] args)
{
FileStream fileStream = new FileStream("d:\\test.txt", FileMode.Open);
//读取所有数据
byte []buffer=new byte[fileStream.Length];
fileStream.Read(buffer, 0, (int)fileStream.Length);
//转换成字符串
String str = Encoding.Default.GetString(buffer);
//转换成数字
int num = int.Parse(str);
//输出数字
Console.WriteLine(num);
}
}
}
这个例子是正常的,不会发异常,接下来我来删除掉test.txt,再运行上面的例子就会产生异常,程序也会非正常结束。
这里个我们就要使用try catch了,如下:
class Program
{
static void Main(string[] args)
{
try
{
FileStream fileStream = new FileStream("d:\\test.txt", FileMode.Open);
//读取所有数据
byte[] buffer = new byte[fileStream.Length];
fileStream.Read(buffer, 0, (int)fileStream.Length);
//转换成字符串
String str = Encoding.Default.GetString(buffer);
//转换成数字
int num = int.Parse(str);
//输出数字
Console.WriteLine(num);
}
catch (FileNotFoundException e)
{
Console.WriteLine("文件不存在!");
}
}
}
上面用到了异常类FileNotFoundException,这个类专用处理文件不存在时的异常。也就是说,只有当产生文件不存在的异常,
catch(FileNotFoundException e)块里的语句才会被执行,如果是其它异常,则不会被执行,像上面那个例子,如果让test.txt文件存在,但把里面的内容改为“a12345”的话。依旧会产生异常,因为int num = int.Parse(str);这个语句。而且程序还会非正常结束。
因为catch(FileNotFoundException e)只负责处理文件不存在的异常。
异常类虽然可以使我们更进一步知道到底是什么原因引起异常的,但也会出现上面所描述的问题。解决这个问题其实很简单。
再加上一个处理任何异常的catch。
示例如下:
class Program
{
static void Main(string[] args)
{
try
{
FileStream fileStream = new FileStream("d:\\test.txt", FileMode.Open);
//读取所有数据
byte[] buffer = new byte[fileStream.Length];
fileStream.Read(buffer, 0, (int)fileStream.Length);
//转换成字符串
String str = Encoding.Default.GetString(buffer);
//转换成数字
int num = int.Parse(str);
//输出数字
Console.WriteLine(num);
}
catch (FileNotFoundException e)
{
Console.WriteLine("文件不存在!");
}
//如果产生的异常不是“文件不存在”,则下面catch里的语句才会被执行
catch(Exception e)
{
Console.WriteLine(e.Message);
}
}
}
类似FileNotFoundException的类还有很多,具体可以到百度上搜。这里只是举个例子。有这样一种类存在。
另外还有try finally组合,finally里面的语句,不管产没产生异常,都会被执行。一般在finally里做一些关闭释放资源的操作。
也有try catch finally组合,不过跟try finally也是一样的,反正记住:finally里的语句最终都会被执行一次。
在try语句里,还可以使用throw来抛出异常,如:
class Program
{
static void Main(string[] args)
{
try
{
//如果输入的是0,就抛出异常
if (int.Parse(Console.ReadLine()) == 0)
throw new Exception();
}
catch (Exception e)
{
Console.WriteLine("异常:不能输入0");
}
}
}