C#中NullReferenceException未被catch块捕获的问题咨询
你的catch块未触发,核心原因是抛出的异常类型和你捕获的NullReferenceException不匹配,或者异常抛出时机超出预期:
若项目未启用运行时非空检查:
string non_nullable_string_1 = (string)nullable_string_1;这行不会抛出异常,non_nullable_string_1会被赋值为null(可空引用类型默认仅做编译时检查,运行时允许null赋值给非nullable引用类型)。后续访问non_nullable_string_1.Length时才会抛出NullReferenceException,此时你的catch块本应捕获它——如果程序仍崩溃,大概率是调试环境默认中断所有未处理异常(比如VS的调试设置),但实际运行时catch块会执行。若项目启用了运行时非空检查(项目文件中设置
<RuntimeNonNullableReferenceTypes>true</RuntimeNonNullableReferenceTypes>):
赋值string non_nullable_string_1 = (string)nullable_string_1;时会直接抛出InvalidCastException(运行时不允许将null转换为非nullable引用类型),而你的catch块仅捕获NullReferenceException,导致异常未被处理,程序直接崩溃。
1. 捕获正确的异常类型
如果启用了运行时非空检查,添加对InvalidCastException的捕获:
string? nullable_string_1 = null; try { string non_nullable_string_1 = (string)nullable_string_1; System.Console.WriteLine(non_nullable_string_1.Length); } catch (System.NullReferenceException nullReferenceException) { System.Console.WriteLine($"出现空引用异常:\"{nullReferenceException.Message}\""); } catch (System.InvalidCastException invalidCastException) { System.Console.WriteLine($"出现无效转换异常:\"{invalidCastException.Message}\""); }
2. 提前做null检查
避免强制转换带来的意外,手动检查null后再赋值:
string? nullable_string_1 = null; try { if (nullable_string_1 is null) { throw new System.ArgumentNullException(nameof(nullable_string_1), "字符串不能为空"); } string non_nullable_string_1 = nullable_string_1; System.Console.WriteLine(non_nullable_string_1.Length); } catch (System.ArgumentNullException ex) { System.Console.WriteLine($"参数异常:\"{ex.Message}\""); } catch (System.NullReferenceException ex) { System.Console.WriteLine($"空引用异常:\"{ex.Message}\""); }
3. 使用空合并运算符规避异常
如果可以接受默认值(比如空字符串),用空合并运算符直接处理null:
string? nullable_string_1 = null; string non_nullable_string_1 = nullable_string_1 ?? string.Empty; System.Console.WriteLine(non_nullable_string_1.Length); // 输出0,无异常抛出
内容的提问来源于stack exchange,提问作者user20311258

