C#中构造带自定义消息的CustomException的最佳实践咨询
自定义异常构造的最佳实践方案
针对你遇到的「在调用Exception基类构造器时还未解析出错误码,无法生成正确异常消息」的问题,以下是几种可行的解决方案及最佳实践:
方案一:静态辅助方法提前解析(推荐)
核心思路是在调用基类构造器前,通过静态方法完成错误码解析和最终消息的生成,同时把解析出的错误码通过out参数传递给构造器主体。这种方式既符合C#构造器的调用规则,又保持代码职责清晰。
示例代码:
public class CustomConnectionException : Exception { public string CustomErrorCode { get; } public HttpStatusCode Code { get; } public string CustomErrorMessage { get; } internal CustomConnectionException(string rawMessage) : base(GenerateBaseMessage(rawMessage, out var errorCode)) { CustomErrorCode = errorCode; Code = HttpStatusCode.InternalServerError; // 可根据错误码调整对应HTTP状态码 CustomErrorMessage = MatchErrorMessage(errorCode); } // 静态方法:提前解析错误码并生成基类需要的异常消息 private static string GenerateBaseMessage(string rawMessage, out string errorCode) { errorCode = ParseErrorCode(rawMessage); var matchedMsg = MatchErrorMessage(errorCode); return $"Error during connection: {matchedMsg}"; } // 错误码解析逻辑(示例) private static string ParseErrorCode(string message) { // 这里实现从原始消息中提取错误码的逻辑,比如正则匹配、字符串分割等 return "CONN-001"; } // 错误码匹配消息逻辑(示例) private static string MatchErrorMessage(string errorCode) { // 这里实现根据错误码返回对应描述的逻辑,比如字典映射、switch判断等 return errorCode switch { "CONN-001" => "连接超时", "CONN-002" => "认证失败", _ => "未知连接错误" }; } }
方案二:重写Exception的Message属性(备选)
如果不想新增静态方法,可以通过重写Message属性来覆盖基类的默认消息。这种方式允许先给基类构造器传一个临时值,后续通过重写属性返回最终的自定义消息。
示例代码:
public class CustomConnectionException : Exception { public string CustomErrorCode { get; } public HttpStatusCode Code { get; } public string CustomErrorMessage { get; } internal CustomConnectionException(string rawMessage) : base("临时占位消息") // 基类构造器传临时值,后续会被重写覆盖 { CustomErrorCode = ParseErrorCode(rawMessage); Code = HttpStatusCode.InternalServerError; CustomErrorMessage = MatchErrorMessage(CustomErrorCode); } // 重写Message属性,返回最终的自定义异常消息 public override string Message => $"Error during connection: {CustomErrorMessage}"; // ParseErrorCode和MatchErrorMessage方法同方案一 }
最佳实践总结
- 优先选择方案一:静态辅助方法的方式既遵守C#构造器的调用规则,又保持代码的职责分离(解析错误码、匹配消息、生成基类消息各自独立),后续维护和扩展更方便。
- 不要尝试直接修改Message字段:Exception的
Message属性底层是只读字段(通过反射修改会破坏封装,属于不良实践),不建议两次设置。 - 保持方法单一职责:不需要合并
ParseErrorCode和MatchErrorMessage,让每个方法只做一件事,代码更易读、易测试。
内容的提问来源于stack exchange,提问作者Luis Angel Urena Lopez
相关产品推荐
相关产品推荐

