第二部分:C#进阶
第4章:异常处理与调试
4.1 异常的捕获与抛出
1. 异常的基本概念
在C#中,**异常(Exception)**是程序运行时发生的错误或意外情况。当异常发生时,程序的正常流程会被中断,转而执行异常处理逻辑。C#提供了结构化异常处理机制,通过try、catch、finally和throw关键字来捕获和处理异常。
2. 异常处理语法
try-catch块
try
{
// 可能抛出异常的代码
int result = 10 / int.Parse("0"); // 除以零会抛出DivideByZeroException
}
catch (DivideByZeroException ex)
{
// 捕获特定类型的异常
Console.WriteLine($"错误:{ex.Message}");
}
catch (Exception ex)
{
// 捕获所有其他异常
Console.WriteLine($"未知错误:{ex.Message}");
}
finally块
无论是否发生异常,finally块中的代码都会执行,通常用于资源清理(如关闭文件或数据库连接)。
FileStream file = null;
try
{
file = File.Open("test.txt", FileMode.Open);
}
catch (FileNotFoundException ex)
{
Console.WriteLine($"文件未找到:{ex.Message}");
}
finally
{
file?.Close(); // 确保文件被关闭
}
3. 抛出异常
使用throw关键字可以主动抛出异常:
if (input < 0)
{
throw new ArgumentException("输入不能为负数", nameof(input));
}
4. 常见异常类型
System.Exception:所有异常的基类。System.NullReferenceException:尝试访问空引用对象的成员。System.IndexOutOfRangeException:数组或集合索引越界。System.IO.IOException:I/O操作错误(如文件读写失败)。System.FormatException:数据格式转换失败(如字符串转数字)。
5. 最佳实践
- 捕获特定异常:优先捕获具体的异常类型,而非直接捕获
Exception。 - 避免空的
catch块:至少记录异常信息或执行恢复操作。 - 合理使用
finally:确保关键资源(如数据库连接)被释放。 - 自定义异常:对于业务逻辑错误,可以定义自己的异常类(继承自
Exception)。
示例:完整的异常处理流程
try
{
Console.Write("请输入一个数字:");
string input = Console.ReadLine();
int number = int.Parse(input); // 可能抛出FormatException
if (number < 0)
{
throw new ArgumentOutOfRangeException(nameof(number), "数字不能为负数");
}
Console.WriteLine($"平方根:{Math.Sqrt(number)}");
}
catch (FormatException)
{
Console.WriteLine("输入的不是有效数字!");
}
catch (ArgumentOutOfRangeException ex)
{
Console.WriteLine(ex.Message);
}
catch (Exception ex)
{
Console.WriteLine($"未知错误:{ex.Message}");
}
finally
{
Console.WriteLine("程序执行完毕。");
}
总结
异常处理是编写健壮C#程序的关键部分。通过合理使用try-catch-finally和自定义异常,可以有效管理运行时错误,提升程序的可靠性和用户体验。
