try-catch 最基本写法和执行逻辑
不加
catch或
finally的
try是语法错误;
try必须至少跟一个
catch或
finally。程序进入
try块后,一旦某行抛出异常(比如
throw new InvalidOperationException()),后续语句立刻停止执行,控制权跳转到匹配的
catch块(按类型从上到下匹配),而不是继续往下跑。
try
{
int x = 10 / 0; // 这里抛出 DivideByZeroException
Console.WriteLine("这行不会执行");
}
catch (DivideByZeroException ex)
{
Console.WriteLine($"捕获到除零异常:{ex.Message}");
}
多个 catch 块的顺序为什么不能乱
异常类型匹配是“就近且精确”,子类异常必须写在父类前面,否则编译报错
CS0160: A previous catch clause already catches all exceptions of this or a super type。比如
NullReferenceException继承自
SystemException,若把
SystemException放前面,后面所有具体异常类型都失效。
catch (ArgumentNullException)→ 可以捕获
ArgumentNullException实例
catch (ArgumentException)→ 可以捕获
ArgumentNullException和
ArgumentOutOfRangeException但后者必须写在前者之后,否则前者永远不会被触发
何时用 catch (Exception) 和什么时候该避免
直接写
catch (Exception)能捕获一切运行时异常,但会掩盖本该由上层处理或需要记录诊断信息的严重问题。它适合做兜底日志、UI 层统一错误提示,但绝不该用来“吞掉异常”后静默继续。 ✅ 合理场景:WPF 窗口事件处理器中记录日志并弹提示框 ❌ 危险操作:在数据访问层捕获
Exception后只写
Console.WriteLine("出错了") 就返回默认值
⚠️ 注意:catch (Exception ex)不捕获
StackOverflowException、
OutOfMemoryException等底层异常(.NET Core+ 默认不传播)
finally 里的代码一定会执行吗
绝大多数情况下会执行,包括
return提前退出、
catch中再次抛异常、甚至
try里
Environment.Exit()之外的所有正常流程。但它无法拦截进程被强制终止(如任务管理器杀进程)、断电、或调用
Environment.FailFast()。
try
{
return "from try";
}
catch
{
return "from catch";
}
finally
{
Console.WriteLine("finally 总会打印"); // 这行会输出
}
复杂点在于:如果
try和
catch都有
return,
finally仍会执行,但它的代码不能改变已确定的返回值(除非是引用类型内部修改)。
