在C#中创建自定义Exception
类型时,为什么认为重载所有这些构造函数是一个好的实践:
Exception()
Exception(String)
Exception(String, Exception)
请见:https://learn.microsoft.com/zh-cn/dotnet/standard/exceptions/best-practices-for-exceptions#include-three-constructors-in-custom-exception-classes 在这些建议中,我没有看到提供任何理由。
如果我想创建一个自定义的
Exception
,用于在调用其他系统时出现未知错误时抛出,为什么认为在此处重写其他构造函数是一种好方法,如果我只需要有关失败系统和导致失败的操作的信息呢?public class ExternalSystemCallException : Exception {
public string FailedSystem { get; }
public string OperationName { get; }
public ExternalSystemCallFailedException(string failedSystem, string operationName) {
FailedSystem = failedSystem;
OperationName = operationName;
}
}
声明:我知道可能还有其他信息可以在此传递,因此这只是一个相当简单的示例。
更新 1:
所以我理解的是,我应该覆盖所有构造函数,但还要额外添加异常所需的所有参数。这正确吗?
例如:
Exception(string failedSystem, string operationName)
: base()
Exception(string failedSystem, string operationName, string message)
: base(message)
Exception(string failedSystem, string operationName, string message, Exception innerException)
: base(message, innerException)
Exception.Message
必须 包含解释出错情况的消息。很多时候,这是在SO问题中记录或报告的唯一信息。然而,你的类却会返回一个空字符串。异常可以被嵌套,实际上自定义异常通常会包装其他异常。你的ExternalSystemCallException
很可能是响应某个其他异常而引发的。用户、支持人员和你在未来都想知道那个异常是什么。 - Panagiotis KanavosException()
- 发生异常,Exception(String)
- 带有消息的异常,Exception(String, Exception)
- 带有消息和内部原因的异常。 - Dmitry BychenkoToString()
方法,否则FailedSystem
和OperationName
不会出现在日志或消息中。格式化字符串和对ToString()
的调用最终将调用Exception.ToString()
,该方法返回Message
、所有内部异常和调用堆栈。如果你想查看这些属性,就需要在构造函数中设置消息。 - Panagiotis Kanavos