.net re:自定义异常的设计:我必须实现默认构造函数吗?";“内部异常”;建造师?

.net re:自定义异常的设计:我必须实现默认构造函数吗?";“内部异常”;建造师?,.net,exception,class-design,serializable,.net,Exception,Class Design,Serializable,对的回答是,自定义异常的“正确”基本实现包括4个因素: [Serializable] public class SerializableExceptionWithoutCustomProperties : Exception { public SerializableExceptionWithoutCustomProperties() { } public SerializableExceptionWithoutCustomProperties(string m

对的回答是,自定义异常的“正确”基本实现包括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)
    {
    }
}
一开始,我就认为对于异常类型来说,这是一个非常糟糕的名字。但是,除此之外

  • 为了二进制序列化的目的,也就是所谓的问题,我必须实现所有4个构造函数吗?我认为为了[Serializable]的目的,我必须提供一个接受类型为(SerializationInfo,StreamingContext)的2个参数的ctor,因为异常派生自System.exception,它本身进行自定义序列化。我能理解。但是为了正确地提供可序列化的异常,我必须实现其他的CTOR吗?我知道,如果我想允许一个类型是xml可序列化的,我需要提供默认的(无操作)构造函数。对于[Serializable]是否也是如此?现在,让我们将自己局限于[Serializable]的狭隘关注点,而不考虑任何关于“框架设计”的更广泛指导原则

  • 转到更广泛的问题:自定义异常应该实现4个通用的CTOR。这一方针背后的理由是什么?如果我设计了一个定制的异常,如果我没有提供一个空/默认的ctor,这真的是不礼貌的,甚至是一个bug吗?如果我不提供允许innerException的ctor,这真的是不礼貌,甚至是一个bug吗?为什么?考虑一下我的自定义异常是在我的库代码中生成的,并且我曾经抛出的唯一实例包括一个消息,而没有内部异常。p>
  • 简而言之,对于不提供附加属性的自定义异常,以下代码是否可以接受



  • 另请参见:.

    建议:如果其他人将使用您的异常,并且这些人将熟悉.NET异常,那么为什么不遵循指导原则呢?它们与.NET Framework使用的相同


    考虑到您定义的自定义异常类型的数量,您是否觉得这项工作太多了?如果是这样,那么这将是遵循指南的另一个原因,该指南规定您不应创建大量自定义异常。

    相关的代码分析警告是CA1032,并且提供了以下理由:

    未能提供全套 构造器可以使它很难 正确处理异常。对于 例如,具有 签名NewException(字符串, 异常)用于创建 由其他原因引起的例外情况 例外情况。如果没有这个构造函数, 您不能创建并抛出 自定义异常的实例 包含内部(嵌套)异常, 托管代码应该做什么 在这种情况下。前三名 异常构造函数是公共的 惯例。第四个构造函数是 在未密封的类中受保护,以及 在封闭的班级里是私人的


    只有您或您的项目团队才能决定您的情况是否需要例外(抱歉…

    嘿,我知道这至少是微软的建议。如果您使用VS2008(或者更早的版本),您可以通过键入

    exception
    

    在编辑器中,按Tab键(两次?)。这将创建它们,让您有机会为该类命名。

    我不喜欢任何答案。我正在确定我提出的解决方案,即。。我可以消除自定义异常上的“普通”构造函数,包括默认构造函数和嵌套构造函数。此外,由于跨appdomain调用,我需要确保序列化工作正常

    我第一次看到有人用“ctor”来表示构造函数O_O。幸运的是,你用了一次完整的单词,这样我就可以理解标题了。我建议你改变你的头衔…啊,很聪明。谢谢你的摘录。这很有帮助。不,没有太多的工作-构造函数已经在我的代码中了。但是,我的代码不使用其中的一半,我想考虑删除它们作为代码清理的一部分。这些异常不打算在我提供的库之外使用。它们是由库抛出的,但我不希望任何其他代码抛出它们。这是典型的,我应该允许,支持吗?如果它们都是为你的库,让它们成为内部类。您仍然应该实现所有这些构造函数,诸如此类-您或以后的维护人员会希望它们“与.NET中的所有其他异常一样”。我想知道,如果自定义异常包含捕获异常发生时发生的某些情况的额外属性,如果我们提供了不需要的构造函数,我们如何强制抛出异常的代码包含这些细节呢?不。总是包含内部异常构造函数,并且总是根据需要使用它。它给出了异常的完整历史记录。
    exception