C# 中提供了丰富的异常类,这些类主要继承自 System.Exception
基类,可根据错误场景分为多个类别。以下是常见的异常类及其适用场景:
一、系统基础异常(继承自 System.SystemException
)
这类异常与 .NET 运行时或系统操作相关,反映底层运行环境的错误。
NullReferenceException
- 最常见的异常之一,当尝试访问
null
对象的成员时抛出。 - 示例:
string s = null; int len = s.Length;
(s
为null
时抛出)。
- 最常见的异常之一,当尝试访问
IndexOutOfRangeException
- 访问数组、集合时索引超出有效范围时抛出。
- 示例:
int[] arr = {1,2,3}; int val = arr[3];
(数组长度为 3,有效索引为 0-2)。
ArgumentOutOfRangeException
- 方法参数值超出允许范围时抛出(与
IndexOutOfRangeException
的区别:前者针对参数,后者针对数组索引)。 - 示例:
List<int> list = new List<int>(); list.Insert(5, 10);
(列表为空时插入索引 5 无效)。
- 方法参数值超出允许范围时抛出(与
ArgumentException
(及子类)- 方法参数无效时的基类,常用子类:
ArgumentNullException
:参数为null
但不允许为null
时(如string
参数必填)。ArgumentOutOfRangeException
:参数值超出范围(上文已提及)。
- 示例:
void SetAge(int age) { if (age < 0) throw new ArgumentOutOfRangeException(nameof(age)); }
。
- 方法参数无效时的基类,常用子类:
InvalidOperationException
- 当对象状态不适合执行当前操作时抛出。
- 示例:对未打开的
FileStream
调用Read()
方法;迭代集合时修改集合(如foreach
中Add
/Remove
)。
NotSupportedException
- 调用不支持的方法或操作时抛出。
- 示例:对只读集合调用
Add()
方法。
NotImplementedException
- 方法尚未实现时的临时占位异常(常用于接口实现的草稿阶段)。
- 示例:
public void Save() { throw new NotImplementedException("保存功能待实现"); }
。
二、IO 相关异常(继承自 System.IO.IOException
)
处理文件、流、目录等操作时的错误。
FileNotFoundException
- 尝试访问不存在的文件时抛出。
- 示例:
File.ReadAllText("不存在的文件.txt")
。
DirectoryNotFoundException
- 目录不存在时抛出(如操作路径中的目录无效)。
PathTooLongException
- 文件或目录路径长度超过系统限制时抛出(如 Windows 中路径通常不能超过 260 字符)。
IOException
(基类)- IO 操作失败的通用异常,其他 IO 异常均继承自它(如文件被占用、权限不足等)。
三、类型与转换相关异常
处理数据类型转换或类型操作时的错误。
InvalidCastException
- 类型转换失败时抛出(通常发生在显式类型转换)。
- 示例:
object obj = "123"; int num = (int)obj;
(字符串无法直接转为 int)。
FormatException
- 数据格式不符合预期时抛出(如字符串转数字失败)。
- 示例:
int.Parse("abc")
(“abc” 不是有效整数格式)。
OverflowException
- 转换或运算结果超出目标类型范围时抛出(如整数溢出)。
- 示例:
int.MaxValue + 1
(需在checked
上下文才会抛出,默认可能不抛)。
四、集合与字典相关异常
针对集合、字典等数据结构的操作错误。
KeyNotFoundException
- 访问字典中不存在的键时抛出。
- 示例:
Dictionary<string, int> dict = new Dictionary<string, int>(); var val = dict["key"];
。
InvalidOperationException
(集合场景)- 集合状态不允许操作时抛出,如:
- 对只读集合调用
Add()
。 - 迭代
List
时调用RemoveAt()
。
- 对只读集合调用
- 集合状态不允许操作时抛出,如:
五、网络相关异常(System.Net
命名空间)
处理网络操作时的错误。
WebException
- HTTP 请求或网络操作失败时抛出(如连接超时、404 错误)。
- 示例:
new WebClient().DownloadString("https://无效地址.com")
。
SocketException
- 底层套接字操作失败时抛出(如端口被占用、连接被拒绝)。
六、其他常见异常
DivideByZeroException
- 整数除法中除数为 0 时抛出(浮点数除法会得到
Infinity
,不抛此异常)。 - 示例:
int result = 10 / 0;
。
- 整数除法中除数为 0 时抛出(浮点数除法会得到
OutOfMemoryException
- 内存不足,无法分配新对象时抛出(严重错误,通常难以恢复)。
StackOverflowException
- 栈溢出(如无限递归调用)时抛出(无法被
try/catch
捕获,会直接终止程序)。
- 栈溢出(如无限递归调用)时抛出(无法被
总结
C# 的异常类设计遵循“具体场景具体异常”的原则,使用时应:
- 抛出具体异常:避免直接抛出
Exception
,而是选择最匹配的子类(如参数为null
时抛ArgumentNullException
)。 - 针对性捕获:根据业务场景捕获特定异常(如文件操作捕获
FileNotFoundException
),避免滥用catch (Exception)
。 - 查看文档:不确定方法会抛出哪些异常时,可参考 .NET 官方文档(如
File.ReadAllText
的文档会说明可能抛出的异常)。
通过合理使用异常类,能让错误信息更清晰,便于调试和问题定位。