C# - Why implement standard exception constructors?
来自msdn,代码分析警告CA1032:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Exception types must implement the following constructors: <ul> <li> public NewException() <li> public NewException(string) <li> public NewException(string, Exception) <li> protected or private NewException(SerializationInfo, StreamingContext) </ul> |
。我理解序列化构造函数背后的目的,但是"需要"其他构造函数背后的理由是什么?为什么我不应该定义任何对我的异常的使用有意义的构造函数呢?如果我不想在不传递消息的情况下抛出MyException,那该怎么办?为什么我应该定义一个无参数的构造函数?如果我希望MyException有一个int属性,而我只希望初始化该属性的构造函数怎么办?
你得到了一些很好的答案。我只是想补充一点,提供这些额外的构造函数并不一定需要很多编码。因为它们已经在基类中实现了,所以您可以简单地让它完成工作:
1 2 3 4 5 6 7 | public class MyCustomException : Exception { public MyCustomException() : base() { } public MyCustomException(string message) : base(message) { } public MyCustomException(string message, Exception innerException) : base(message, innerException) { } // and so on... } |
因此,您只需要在异常的行为与基类的行为不同的地方实现代码。
这是警告,不是要求。这基本上是最不令人惊讶的原则。提供全部4个选项,使习惯于"常规"C例外的人更容易使用您的C例外。如果您有充分的理由忽略指导原则,那么就这样做。但它将打破某些使用场景,并使类的直观性有所下降。
实现标准异常构造函数允许人们以一种标准的、熟悉的方式使用您的异常,该方法内置于所有现有的.NET异常中。前三个可以是可选的,如果出于某种原因您不想使用其中的一个(尽管您为什么希望我无法理解),但是最后一个是反序列化构造函数,如果您希望在任何类型的分布式环境中支持您的异常(NET远程处理、ASP.NET Web服务、WCF等),那么它是非常重要。
如果没有反序列化构造函数和[serializable]属性,异常将无法在分布式环境中运行,并可能导致其他问题。鉴于这一点,以及熟悉C开发人员的方面,最好实现至少4个标准异常构造函数,并用[可序列化]标记异常。
无参数和序列化构造函数由通用"异常路由"代码使用,这些代码需要在域之间(例如,在服务和客户机之间的Internet上)移动异常。
采用另一个
最后,还有一个接受消息字符串的字符串,这有助于合理地一致地使用异常。
好吧,接受内部异常的构造函数对于使自定义异常正常可用是非常必要的。如果没有它,如果有人捕获了您的异常,那么在保存原始异常(以及它所携带的信息,如堆栈跟踪)的同时,他们就无法触发更具描述性或适当的异常。