165 lines
3.1 KiB
Markdown
165 lines
3.1 KiB
Markdown
# 第八课:异常处理
|
||
|
||
## 什么是异常
|
||
|
||
异常 = 程序运行时的错误,导致程序无法正常继续。
|
||
|
||
```csharp
|
||
int[] numbers = { 1, 2, 3 };
|
||
int x = numbers[10]; // 索引越界 → 抛出 IndexOutOfRangeException
|
||
```
|
||
|
||
## try / catch / finally
|
||
|
||
```csharp
|
||
try
|
||
{
|
||
// 可能出错的代码放这里
|
||
int[] numbers = { 1, 2, 3 };
|
||
int x = numbers[10];
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 捕获异常并处理
|
||
Console.WriteLine($"出错了: {ex.Message}");
|
||
}
|
||
finally
|
||
{
|
||
// 无论是否出错,都会执行(通常放清理代码)
|
||
Console.WriteLine("无论怎样都会执行");
|
||
}
|
||
```
|
||
|
||
## 捕获特定异常类型
|
||
|
||
```csharp
|
||
try
|
||
{
|
||
int a = int.Parse("abc"); // 格式错误
|
||
}
|
||
catch (FormatException ex)
|
||
{
|
||
Console.WriteLine("格式错误");
|
||
}
|
||
catch (OverflowException ex)
|
||
{
|
||
Console.WriteLine("数字溢出");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"未知错误: {ex.Message}");
|
||
}
|
||
```
|
||
|
||
## 常见异常类型
|
||
|
||
| 异常类型 | 触发场景 |
|
||
|----------|----------|
|
||
| `FormatException` | 格式错误(`int.Parse("abc")`) |
|
||
| `NullReferenceException` | 空对象访问(`obj.Method()`,`obj` 为 null) |
|
||
| `IndexOutOfRangeException` | 数组越界 |
|
||
| `FileNotFoundException` | 文件不存在 |
|
||
| `DivideByZeroException` | 除数为零 |
|
||
| `InvalidOperationException` | 操作无效状态 |
|
||
|
||
## throw 抛出异常
|
||
|
||
```csharp
|
||
static void SetAge(int age)
|
||
{
|
||
if (age < 0 || age > 150)
|
||
{
|
||
throw new ArgumentException("年龄必须在 0-150 之间");
|
||
}
|
||
Console.WriteLine($"年龄设置为: {age}");
|
||
}
|
||
```
|
||
|
||
```csharp
|
||
try
|
||
{
|
||
SetAge(-5);
|
||
}
|
||
catch (ArgumentException ex)
|
||
{
|
||
Console.WriteLine($"参数错误: {ex.Message}");
|
||
}
|
||
```
|
||
|
||
## 自定义异常
|
||
|
||
```csharp
|
||
class MicrophoneException : Exception
|
||
{
|
||
public MicrophoneException(string message) : base(message) { }
|
||
public MicrophoneException(string message, Exception inner) : base(message, inner) { }
|
||
}
|
||
```
|
||
|
||
## finally 的作用
|
||
|
||
```csharp
|
||
FileStream file = null;
|
||
try
|
||
{
|
||
file = new FileStream("test.txt", FileMode.Open);
|
||
// 读取文件...
|
||
}
|
||
catch (FileNotFoundException ex)
|
||
{
|
||
Console.WriteLine("文件不存在");
|
||
}
|
||
finally
|
||
{
|
||
// 确保文件被关闭
|
||
file?.Close();
|
||
}
|
||
```
|
||
|
||
## using 语句(更简洁)
|
||
|
||
```csharp
|
||
// using 自动释放资源(相当于 try-finally)
|
||
using (FileStream file = new FileStream("test.txt", FileMode.Open))
|
||
{
|
||
// 使用 file
|
||
} // 作用域结束后自动 Close()
|
||
```
|
||
|
||
## 实际项目应用
|
||
|
||
```csharp
|
||
try
|
||
{
|
||
// 尝试连接麦克风
|
||
microphone.Connect();
|
||
}
|
||
catch (DeviceNotFoundException ex)
|
||
{
|
||
Console.WriteLine("麦克风未找到,请检查连接");
|
||
ShowReconnectDialog();
|
||
}
|
||
catch (UnauthorizedAccessException ex)
|
||
{
|
||
Console.WriteLine("没有权限访问麦克风");
|
||
RequestPermission();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"未知错误: {ex.Message}");
|
||
LogError(ex);
|
||
}
|
||
```
|
||
|
||
## 不要过度捕获异常
|
||
|
||
```csharp
|
||
// ✗ 不好:捕获所有异常但不处理
|
||
try { DoSomething(); }
|
||
catch { }
|
||
|
||
// ✓ 好:只捕获能处理的异常
|
||
try { Connect(); }
|
||
catch (DeviceNotFoundException ex) { ShowError(); }
|
||
```
|