.NET 8中Exception子类序列化构造函数过时的最佳实践
核心结论
在.NET 8.0及后续现代.NET版本中,完全可以不再编写接收SerializationInfo和StreamingContext的序列化构造函数,不支持基于格式化程序的序列化的自定义Exception类是完全可接受的。
逐个解答你的疑问
1. 保留该构造函数是否存在问题?
保留本身不会触发运行错误,但会持续弹出SYSLIB0051警告,而且该构造函数属于已废弃的技术体系,后续.NET版本可能进一步限制甚至移除相关依赖API,属于冗余且过时的代码,没必要保留。
2. .NET 8.0中是否有调用它的场景?
几乎没有。这个构造函数仅服务于基于格式化程序的序列化,这套机制从.NET Core 1.0起就被废弃,.NET 8里没有官方推荐的场景会主动调用它。极端情况仅可能是你手动调用,或项目依赖了非常老旧的第三方库,但这种情况极少。
3. 省略它是否违反契约?
不违反。传统.NET Framework要求Exception子类必须实现该构造函数以支持序列化,但现代.NET(Core/.NET 5+)已不再强制这个契约。Exception基类虽仍保留该构造函数,但已标记为过时,官方明确不推荐子类再实现它。
4. 是所有基于格式化程序的序列化都已过时,还是仅Exception对象的此类序列化过时?
所有基于格式化程序的序列化(比如BinaryFormatter、NetDataContractSerializer这类)在现代.NET中都已标记为过时,不止是Exception的相关实现。这类序列化存在严重安全风险,官方早已推荐System.Text.Json、Newtonsoft.Json或Protobuf等现代序列化方案。
5. 是否因该序列化主要用于已被.NET Core及后续版本弃用的.NET远程处理,故认为不会再被使用?
没错。基于格式化程序的序列化核心场景就是.NET远程处理(.NET Remoting),而.NET Remoting在.NET Core时代已被彻底移除,现代.NET没有官方替代方案,这套序列化机制已失去核心使用场景,完全可以抛弃。
6. 核心疑问:是否无需再编写该构造函数?当前编写不支持基于格式化程序序列化的Exception类是否可接受?
- 完全不需要再编写这个构造函数。
- 不支持基于格式化程序序列化的自定义Exception类是完全可接受的,符合现代.NET的设计规范和官方推荐。
内容的提问来源于stack exchange,提问作者Jonathan Gilbert

