You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#自定义Exception:重写的Message属性与构造函数执行顺序?

问题解答

1. 构造函数与重写Message属性的有效性

你第一种写法里重写Message属性的方式是完全有效的,能达到你想要的效果:无论实例化异常时构造函数传入什么message参数,外部访问该异常的Message属性时,都会得到你定义的固定值"Email or password is incorrect"。构造函数的调用逻辑不会影响你对Message属性的重写——这是子类对基类属性的多态覆盖,只要属性被访问,就会执行子类的重写逻辑。

2. 执行顺序说明

构造函数和重写的Message属性不是同一阶段执行的:

  • 构造函数在实例化异常对象时立即执行:先调用基类Exception的构造逻辑,再执行子类UserNotFoundException的构造代码,整个过程属于对象初始化阶段;
  • 重写的Message属性是延迟执行的:它只有在被外部代码主动访问(比如var ex = new UserNotFoundException(); Console.WriteLine(ex.Message);)的时候才会被求值,不会在构造阶段运行。

3. 避免代码重复的优化写法

针对你第二种写法的重复问题,可以通过构造函数链+常量定义来消除重复,同时保持逻辑清晰:

public class UserNotFoundException : Exception
{
    // 把默认消息定义为常量,统一维护
    private const string DefaultErrorMessage = "Email or password is incorrect";

    public UserNotFoundException() : this(DefaultErrorMessage)
    {
    }

    public UserNotFoundException(string? message) : this(message, null)
    {
    }

    public UserNotFoundException(string? message, Exception? innerException) 
        : base(message ?? DefaultErrorMessage, innerException)
    {
    }
}

这种写法的好处是:

  • 默认消息只定义一次,避免重复硬编码;
  • 通过构造函数链复用逻辑,所有构造最终都调用最底层带完整参数的构造函数;
  • 支持自定义消息(如果需要的话),同时在传入null时自动使用默认消息。

如果你确实需要强制固定Message值,不允许自定义,那第一种重写Message的写法更直接,但要注意:Exception基类的ToString()方法会用到Message属性,这时候也会调用你的重写逻辑,符合预期。

内容的提问来源于stack exchange,提问作者O S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 14:17:30