首页 > 编程笔记 > C#笔记 阅读:9

C# try catch finally的用法(非常详细)

C# 中,有时也可以将程序错误(error)称为程序异常(exception),相信每一位写程序的人都会常常碰上程序异常。

过去碰上程序异常,程序终止执行的同时会出现错误信息,错误信息内容通常显示 Unhandled exception,然后列出异常报告。C# 提供功能可以让我们捕捉异常并撰写异常处理程序,当发生的异常被我们捕捉后会去执行异常处理程序,然后程序可以继续执行。

以一个除数为 0 的错误为例开始说明:
double? Division(int x, int y)
{
    return x / y;
}
Console.WriteLine(Division(9, 3));    // 输出 9 / 3
Console.WriteLine(Division(3, 0));    // 输出 3 / 0
Console.WriteLine(Division(4, 2));    // 输出 4 / 2
执行结果为:

3
Unhandled exception. System.DivideByZeroException: Attempted to divide by zero.

上述程序在执行第 5 行时,一切还是正常。但是到了执行第 6 行时,因为第 2 个参数是 0,导致发生“DivideByZeroException”也就是尝试除以 0 的错误,所以整个程序就执行终止了。

其实对于上述程序而言,若是程序可以执行到第 7 行,是可以正常得到执行结果的,可是程序第 6 行已经造成程序终止了,所以无法执行第 7 行。

C# try catch指令

接下来讲解如何捕捉异常并设计异常处理程序,发生的异常被捕捉后程序会执行异常处理程序,然后跳开异常位置,再继续往下执行。这时要使用 try-catch 指令,它的语法格式如下:
try
{
    系列工作指令        // 预先设想可能引发错误异常的指令
}
catch ( ExceptionName )
{
    异常处理程序        // 通常是指异常原因方便修正
}
上述语句会执行 try 下面的区块指令,如果正常则跳离 catch 部分,如果指令有错误异常,则检查此异常是否为 ExceptionName 所指的错误,如果是则代表异常被捕提了,这时会执行 catch 下面区块的异常处理指令。

例如:
double? Division(int x, int y)
{
    try
    {
        return x / y;
    }
    catch (DivideByZeroException)
    {
        Console.WriteLine("除数不可为 0");
        return null;
    }
}
Console.WriteLine(Division(9, 3));    // 输出 9 / 3
Console.WriteLine(Division(3, 0));    // 输出 3 / 0
Console.WriteLine(Division(4, 2));    // 输出 4 / 2
执行结果为:

3
除数不可为 0

2

上述程序执行第 13 行时,会将参数 (9, 3) 带入 Division() 函数,由于执行 try 的指令“x / y”没有问题,所以可以执行“return x / y”,这时 C# 将跳过 catch 的指令。

当程序执行第 14 行时,会将参数 (3, 0) 带入 Division() 函数,由于执行 try 的指令“x / y”产生了除数为 0 的“DivideByZeroException”异常,这时 C# 会找寻是否有处理这类异常的 catch(DivideByZeroException) 存在,如果有就表示此异常被捕提,就去执行相关的错误处理程序。

此例中是执行第 9~10 行,输出“除数不可为0”的错误,同时因为 Division() 函数是 double?,所以必须要有回传值,此例回传 null。函数返回后打印出结果 null,None 是一个对象表示结果不存在,所以输出空白行,最后返回程序第 15 行,继续执行相关指令。

从上述可以看到,程序增加了 try-catch 后,若是异常被捕提,出现的异常信息就比较友善了,同时不会有程序中断的情况发生。

特别需留意的是在 try catch 的使用中,如果在 try 后面的指令产生异常时,这个异常不是我们设计的 catch 异常对象,表示异常没被捕提到,这时程序依旧会像文章开头的实例程序一样,直接出现错误信息,然后程序终止。

C# try catch finally的用法

C# 在 try catch 中又增加了 finally 区块,不论是否捕捉到错误 C# 都会执行此 finally 区块的内容。
try
{
    系列工作指令        // 预先设想可能引发错误异常的指令
}
catch ( ExceptionName )
{
    异常处理程序        // 通常是指异常原因方便修正
}
finally
{
    一定要执行的内容
}

例如:
double? Division(int x, int y)
{
    try
    {
        return x / y;
    }
    catch (DivideByZeroException)
    {
        Console.WriteLine("除数不可为 0");
        return null;
    }
    finally
    {
        Console.WriteLine("Division()测试结束");
    }
}
Console.WriteLine(Division(9, 3));    // 输出 9 / 3
Console.WriteLine(Division(3, 0));    // 输出 3 / 0
Console.WriteLine(Division(4, 2));    // 输出 4 / 2
执行结果为:

Division()测试结束
3
除数不可为 0
Division()测试结束
Division()测试结束
2

上述 try catch finally 内一定会执行 finally 区块的内容,所以一定会先执行第 15 行的输出“Division()测试结束”字符串,然后再结束 Division() 函数。

C#设计多组异常处理程序

在程序设计时,有太多不可预期的异常发生,所以我们需要知道设计程序时需要同时设计多个异常处理程序。

下表罗列了 C# 程序中常见的异常对象:

C# 程序中常见的异常对象
异常对象名称 说明
ArgumentException 非空参数传递给方法
ArgumentNullException 空参数传递给方法
ArgumentOutOfRangeException 参数超出有效范围
DivideByZeroException 整数除以 0
FileNotFoundException 文件不存在
FormatException 格式错误,如字符串转整数格式错误
IndexOutOfRangeException 索引超出范围
InvalidOperationException 对象状态是无效的
KeyNotFoundException 键不存在
NotSupportedException 方法或操作目前没有支持
NullReferenceException 程序存取空对象
OverflowException 代数运算或转换发生溢位
OutOfMemoryException 内存不足
StackOverflowException 栈溢出
TimeoutException 配置操作的时间区段结束

在 try catch 的使用中,可以设计多个 catch 捕捉多种异常,此时语法如下:
try
{
    系列工作指令        // 预先设想可能引发错误异常的指令
}
catch ( ExceptionName e1 )
{
    Console.WriteLine(e1.Message)    // 输出系统异常说明文字
}
catch ( ExceptionName e2 )
{
    Console.WriteLine(e2.Message)    // 输出系统异常说明文字
}

例如:
double? Division(int x, int y)
{
    try
    {
        return x / y;
    }
    catch (DivideByZeroException e1)
    {
        Console.WriteLine(e1.Message);
        return null;
    }
    catch (ArgumentOutOfRangeException e2)
    {
        Console.WriteLine(e2.Message);
        return null;
    }
}
Console.WriteLine(Division(9, 3));    // 输出 9 / 3
Console.WriteLine(Division(3, 0));    // 输出 3 / 0
Console.WriteLine(Division(4, 2));    // 输出 4 / 2
执行结果为:

3
Attempted to divide by zero.

2

上述第 12~16 行就是第 2 组用来捕捉错误信息的。

C#捕捉所有异常

程序设计时的许多异常是我们不可预期的,很难一次设想周到,C# 提供语法让我们可以一次捕捉所有异常,此时 try catch 语法如下:
try
{
    系列工作指令        // 预先设想可能引发错误异常的指令
}
catch
{
    异常处理程序        // 输出系统异常说明文字
}
上述 catch 右边没有任何异常对象名称,表示如果发生异常会自动执行此区块指令。

例如:
double? Division(int x, int y)
{
    try
    {
        return x / y;
    }
    catch
    {
        Console.WriteLine("异常发生");
        return null;
    }
}
Console.WriteLine(Division(9, 3));    // 输出 9 / 3
Console.WriteLine(Division(3, 0));    // 输出 3 / 0
Console.WriteLine(Division(4, 2));    // 输出 4 / 2
执行结果为:

3
异常发生

2

C# Exception

在 try catch 语法中,如果在 catch 右边的小括号内放“Exception e”,也可以捕捉所有的异常,此时语法如下:
try
{
    系列工作指令        // 预先设想可能引发错误异常的指令
}
catch (Exception e)
{
    异常处理程序        // 输出系统异常说明文字
}

例如:
double? Division(int x, int y)
{
    try
    {
        return x / y;
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
        return null;
    }
}
Console.WriteLine(Division(9, 3));    // 输出 9 / 3
Console.WriteLine(Division(3, 0));    // 输出 3 / 0
Console.WriteLine(Division(4, 2));    // 输出 4 / 2
执行结果为:

3
Attempted to divide by zero.

2

相关文章