关于:自定义异常的设计:我必须实现默认构造函数吗?“内部异常”构造函数?
-
21-08-2019 - |
题
答案是 使异常可序列化的正确方法是什么? 表示自定义异常的“正确”基本实现包括 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)
{
}
}
我马上就会说,对于 Exception 类型来说,这是一个非常糟糕的名称。但是,除此之外,
为了二进制序列化的目的,这就是SO问题所指的, 我必须实现所有 4 个构造函数吗?我认为出于 [Serialized] 的目的,我必须提供一个接受 2 个类型的参数(SerializationInfo、StreamingContext)的 ctor,因为异常源自 System.Exception,它本身执行自定义序列化。我能理解。但我必须执行其他演员吗? 为了正确提供可序列化的异常?我知道,如果我想允许类型可 xml 序列化,我需要提供默认(无操作)ctor。[Serialized] 也是如此吗?暂时,让我们将自己限制在 [Serialized] 的狭隘关注范围内,而忽略任何有关“框架设计”的更广泛的指导方针。
转向更广泛的问题: 指南说 那 自定义异常应该实现 4 个常见因素. 。该指南背后的理由是什么?如果我设计一个自定义异常,如果我不提供空/默认构造函数,这真的是很不礼貌,甚至是一个错误吗?如果我不提供允许innerException 的ctor,这真的是很不礼貌,甚至是一个错误吗?为什么?考虑这样的情况:我的自定义异常是在我的库代码中生成的,并且我抛出的唯一实例包括一条消息,并且没有innerException。
简而言之,对于不提供其他属性的自定义异常,以下代码是否可以接受?
[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) { }
}
也可以看看: 冬日博客:使异常可序列化.
解决方案 4
我不喜欢任何答案。我正在确定我提出的解决方案,即..我可以消除自定义异常中的“正常”构造函数,包括默认构造函数和嵌套构造函数。另外,由于跨应用程序域调用,我需要确保序列化有效。
其他提示
相关的代码分析警告为 CA1032,并且 参考页 提供了这样的理由:
不提供完整的构造函数可能会使很难正确处理异常。例如,使用签名newException(字符串,异常)的构造函数来创建由其他异常引起的异常。没有此构造函数,您将无法创建并投掷包含内部(嵌套)异常的自定义异常的实例,这是托管代码在这种情况下应该做的。前三个 异常构造函数由 公约。第四个构造函数是 在非密封类中受保护,以及 在密封类中是私有的。
只有您或您的项目团队可以决定您的情况是否需要例外(抱歉......)
嘿,我知道至少微软是这么建议的。如果您使用 VS2008(或者可能更早的版本),您可以通过键入以下内容轻松让 Visual Studio 为您创建它们
exception
在编辑器中并按 Tab 键(两次?)。这将创建它们,让您有机会为类指定新名称。
建议:如果其他人将使用您的异常,并且由于这些其他人将熟悉 .NET 异常,那么为什么不遵循指南呢?它们与 .NET Framework 使用的相同。
考虑到您定义的自定义异常类型的数量,您是否觉得这工作量太大?如果是这样,那么这将是遵循指南的另一个原因,该指南指定您不应创建大量自定义异常。