.net - 重新 : design of custom exceptions: must I implement the default constructor? "inner exception"构造函数?

标签 .net exception class-design serializable

What is the correct way to make exceptions serializable?的答案表示自定义异常的“正确”基本实现包括 4 个因素:

[Serializable]
public class SerializableExceptionWithoutCustomProperties : Exception
{
    public SerializableExceptionWithoutCustomProperties()
    {
    }

    public SerializableExceptionWithoutCustomProperties(string message) 
        : base(message)
    {
    }

    public SerializableExceptionWithoutCustomProperties(string message, Exception innerException) 
        : base(message, innerException)
    {
    }

    // Without this constructor, deserialization will fail
    protected SerializableExceptionWithoutCustomProperties(SerializationInfo info, StreamingContext context) 
        : base(info, context)
    {
    }
}

马上,我会说这对于异常类型来说是一个非常糟糕的名称。但是,除此之外,

  1. 出于二进制序列化的目的,这就是 SO 问题所指的内容,我必须实现所有 4 个构造函数吗?我认为出于 [Serialized] 的目的,我必须提供一个接受 2 个类型的参数(SerializationInfo、StreamingContext)的 ctor,因为异常源自 System.Exception,它本身执行自定义序列化。我能理解。但是我必须实现其他成员才能正确提供可序列化的异常吗?我知道,如果我想允许类型可 xml 序列化,我需要提供默认(无操作)ctor。 [Serialized] 也是如此吗?现在,让我们将自己限制在 [Serialized] 的狭隘关注点上,而忽略任何有关“框架设计”的更广泛的指导方针。

  2. 转向更广泛的问题:The guidelines say 自定义异常应该实现 4 个常见因素。该指南背后的理由是什么?如果我设计一个自定义异常,如果我不提供空/默认构造函数,这真的是很不礼貌,甚至是一个错误吗?如果我不提供允许innerException 的ctor,这真的是很不礼貌,甚至是一个错误吗?为什么?考虑这样的情况:我的自定义异常是在我的库代码中生成的,并且我抛出的唯一实例包括一条消息,并且没有innerException。

  3. 简而言之,对于不提供其他属性的自定义异常,以下代码是否可以接受?


[Serializable]
public class CustomException : Exception
{
    public CustomException(string message) : base(message) { }

    // Without this constructor, deserialization will fail
    protected CustomException(SerializationInfo info, StreamingContext context) 
        : base(info, context) { }
}

另请参阅:Winterdom blog: Make exceptions Serializable .

最佳答案

相关的代码分析警告是 CA1032,reference page提供了这样的理由:

Failure to provide the full set of constructors can make it difficult to correctly handle exceptions. For example, the constructor with the signature NewException(string, Exception) is used to create exceptions that are caused by other exceptions. Without this constructor, you cannot create and throw an instance of your custom exception that contains an inner (nested) exception, which is what managed code should do in such a situation. The first three exception constructors are public by convention. The fourth constructor is protected in unsealed classes, and private in sealed classes.

只有您或您的项目团队才能决定您的情况是否需要异常(exception)(抱歉......)

关于.net - 重新 : design of custom exceptions: must I implement the default constructor? "inner exception"构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1068103/

相关文章:

.net - 有没有办法在不使用外部库的情况下在 C# 中生成大素数?

java - 在静态 try-catch 中分配静态最终变量

c# - 类型初始化异常 : The type initializer for '<Module>' threw an exception

class - UML - 边界的子类可以充当 Controller 吗?

c# - 什么时候没有方法的 C# 类是糟糕的设计?

.net - 错误ADB0020 : Mono. AndroidTools.IncompatibleCpuAbiExceptiopn: 包不支持此设备的CPU架构

c# - 有没有比 TextWriter/StringBuilder 更高效的文本后台处理程序

asp.net - 如何根据角色显示或隐藏控件 - ASP.NET MVC 4 Razor

java - 文件.createNewFile() : How to handle "unreported exception" error?

c++ - 类之间的信号/槽和类的设计