c#如何自定义异常_c#自定义异常看这一篇就够了_保姆级教程
C#自定义异常必须继承System.Exception或其子类,否则编译报错CS0155;需实现4个构造函数以支持序列化,推荐加ErrorCode等属性但须正确处理序列化,并遵循命名、注释和轻量原则。

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
在C#开发中,自定义异常是处理特定业务错误的常用手段。但很多开发者存在一个误区:认为只要继承Exception类即可。实际上,C#自定义异常有更严格的规范:**它必须直接继承System.Exception,或者继承其任意一个子类**。这是CLR层面的硬性要求,违反此规则将直接导致编译错误CS0155: Cannot throw an object that does not inherit from 'System.Exception'。
为什么自定义异常必须继承 System.Exception
这源于C#异常处理机制的底层设计。公共语言运行时(CLR)规定,所有可被throw关键字抛出的对象,其类型必须是System.Exception的派生类。你可以通过一个简单测试验证:创建一个空类class MyError { },然后尝试执行throw new MyError();,编译器会立即阻止这一操作。
Exception类是CLR唯一认可的“合法异常根类型”,其内部机制确保了异常构造逻辑的封闭性。- 注意一个历史遗留问题:避免继承
ApplicationException。该类已被微软标记为[Obsolete],官方文档明确建议不再使用。 - 如果你的异常需要体现特定的语义层次,最佳实践是继承已有的具体异常类型,例如
ArgumentException(参数错误)或InvalidOperationException(无效操作),而非创建新的根类。
实现自定义异常的标准写法(含序列化支持)
在.NET Core/.NET 5+及更高版本中,序列化支持依然至关重要。如果你的异常可能用于跨进程通信、WCF、gRPC或日志持久化场景,忽略序列化构造函数将导致异常信息在传输或存储过程中丢失。
一个健壮且符合规范的自定义异常类,通常需要实现以下四个核心构造函数:
- 无参构造函数:主要供反序列化机制调用。
- 接收
(string message)的构造函数:最常用的场景,用于传递错误描述。 - 接收
(string message, Exception innerException)的构造函数:用于构建异常链,保留内部异常的根本原因。 - 受保护的
(SerializationInfo info, StreamingContext context)构造函数:确保在.NET Framework及需要显式序列化的.NET Core场景中正常工作。
以下是一个标准的自定义异常实现示例:
public class InvalidOrderStateException : Exception
{
public InvalidOrderStateException() { }
public InvalidOrderStateException(string message) : base(message) { }
public InvalidOrderStateException(string message, Exception innerException)
: base(message, innerException) { }
protected InvalidOrderStateException(SerializationInfo info, StreamingContext context)
: base(info, context) { }
}
如何为自定义异常添加额外属性
在许多业务场景中,仅靠错误信息不足以定位问题。为异常添加额外属性(如ErrorCode、OrderId、UserId)能极大提升调试效率。但需注意以下关键点:
- 所有自定义属性必须在**每一个**构造函数中被正确初始化。特别是在反序列化构造函数中,必须从
info参数中读取并还原属性值,否则序列化/反序列化后属性将变为默认值。 - 如果附加信息仅用于辅助日志记录或临时调试,更推荐使用
Exception.Data字典属性。它无需修改异常类结构,且会自动参与序列化过程。 - 安全警告:切勿将敏感信息(如用户密码、API密钥、访问令牌)存入异常属性。异常对象可能被记录到明文日志或意外暴露给客户端,导致安全风险。
以下是一个安全添加ErrorCode属性的完整示例:
public class PaymentFailedException : Exception
{
public int ErrorCode { get; }
public PaymentFailedException(int errorCode, string message)
: base(message)
{
ErrorCode = errorCode;
}
protected PaymentFailedException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
ErrorCode = info.GetInt32(nameof(ErrorCode));
}
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(nameof(ErrorCode), ErrorCode);
base.GetObjectData(info, context);
}
}
提升自定义异常工程化水平的细节
要编写专业级的自定义异常,还需关注以下实践细节:
[Serializable]特性:在.NET Framework中必须显式添加;在.NET Core/.NET 5+中虽非强制,但若缺失会导致GetObjectData方法不被调用,自定义序列化逻辑失效。- 添加XML注释:这不仅提升代码可读性,更能在Visual Studio智能提示、IntelliSense及生成的API文档中直接显示,对团队协作与代码维护至关重要。
- 命名规范:异常类名应以
Exception结尾,这是.NET命名约定,也是Roslyn Analyzer等代码分析工具的检查项。 - 保持轻量:避免在异常构造函数中执行耗时操作(如文件I/O、网络请求、复杂计算)。异常对象的创建应快速、无副作用。
最后,理解异常的本质比记住所有语法更重要:**异常一旦被抛出,即标志着正常的程序流程已中断。其核心职责是清晰、准确地传达“错误类型、发生位置及根本原因”,而非执行修复或重试逻辑。** 把握这一原则,你的异常设计将更加清晰、有效。
相关攻略
C ReadOnlySpan 使用指南:高性能只读内存切片优化技巧【高级教程】 在 NET 高性能编程实践中,尤其是在字符串处理场景,一个公认的高效策略是:直接采用 ReadOnlySpan 来替代传统的 string 参数以及中间的 Substring 调用。这是目前实现零分配、低开销处理的最
SQL Server分页首选OFFSET-FETCH,需配合ORDER BY且参数化传值;EF Core用Skip Take自动翻译,避免内存分页;大数据量时应改用游标分页。 SQL Server 中用 OFFSET-FETCH 做分页最直接 说到在SQL Server里做分页,2012及以上版本提
C 万级数据批量插入:SqlBulkCopy 实战精要 在C 中进行大规模数据插入,性能是首要考量。当数据量达到万级甚至更高时,常规的逐条插入方法会迅速成为性能瓶颈。那么,有没有一种既高效又稳定的解决方案呢?答案是肯定的。 用 SqlBulkCopy 实现高速批量插入 开门见山地说,在C 生态中,
C 中使用TestContainers进行集成测试:最佳实践与常见坑点 想在 NET 里玩转 TestContainers?这事儿说简单也简单,说麻烦也麻烦。简单在于,它确实能让你用几行代码就拉起一个数据库或中间件进行测试;麻烦在于,从环境配置到代码编写,每一步都有几个“经典”的坑在等着你。今天,
C WPF Canvas画布绘图完全指南:代码动态绘制图形与连线详解 Canvas直接添加子元素导致错位或不显示的解决方案 许多C 开发者在初次使用WPF Canvas控件进行动态绘图时,常会遇到一个典型问题:为何通过代码添加的Rectangle矩形或Line线条无法正常显示,或者出现位置偏移?
热门专题
热门推荐
蔚来2026年4月交付数据发布:多品牌齐头并进,累计交付突破110万台 最新数据显示,2026年4月,蔚来公司整体交付新车达到29,356台,实现了22 8%的同比增长。这份成绩单背后,是旗下多品牌矩阵的共同发力。 具体来看,作为基石的蔚来品牌交付了19,024台;而面向主流家庭市场的乐道品牌表现稳
集中治理电视剧侵权传播动员会召开,行业版权保护再升级 近日,国家广播电视总局的一场动员会,为视听行业的版权保护工作按下了加速键。这场聚焦于集中治理电视剧侵权传播的会议,传递出的信号明确而有力:打击侵权盗版,维护健康生态,已成行业共识与当务之急。 侵权之害:动摇行业根基 会议一针见血地指出,电视剧乃至
维信诺闪耀SID DW 2026:以“屏台”技术硬核实力,定义下一代显示升级方向 五月初的洛杉矶,再次成为全球显示技术的焦点。当地时间5月5日至7日,国际显示周(SID Display Week)如期而至,这场行业顶级盛会向来是窥探未来显示趋势的绝佳窗口。今年,维信诺携其全尺寸创新成果亮相,可谓阵容
2026年Q1全球手机市场:苹果的“统治力”与安卓的“哑铃困境” 5月6日,市场研究机构Counterpoint发布了2026年第一季度的全球智能手机销量榜单。数据揭示了一个近乎“单方面碾压”的格局:苹果在高端市场展现出绝对的统治力,而安卓阵营则显得有些“无力招架”。 仔细看这份TOP10榜单,iP
快科技5月6日消息:7年前丢的手机发回定位,机主成功找回 今天,一则“7年前丢的手机发回定位,机主找回”的消息,冲上了网络热搜榜。 事件引发广泛讨论后,魅族客服方面向媒体做出了最新回应:只要机主曾在系统中挂失过手机,并且这部手机处于开机联网状态、同时登录了原机主的魅族Flyme账号,手机确实会自动拍





