首页 > 编程语言 >c#如何自定义异常_c#自定义异常看这一篇就够了_保姆级教程

c#如何自定义异常_c#自定义异常看这一篇就够了_保姆级教程

来源:互联网 2026-04-15 09:05:31

C#自定义异常必须继承System.Exception或其子类,否则编译报错CS0155;需实现4个构造函数以支持序列化,推荐加ErrorCode等属性但须正确处理序列化,并遵循命名、注释和轻量原则。 在C#中创建自定义异常,其核心要求是必须继承System.Exception或其任意子类。违反此规

C#自定义异常必须继承System.Exception或其子类,否则编译报错CS0155;需实现4个构造函数以支持序列化,推荐加ErrorCode等属性但须正确处理序列化,并遵循命名、注释和轻量原则。

c#如何自定义异常_c#自定义异常看这一篇就够了_保姆级教程

在C#中创建自定义异常,其核心要求是必须继承System.Exception或其任意子类。违反此规则将导致编译错误CS0155: Cannot throw an object that does not inherit from 'System.Exception'

长期稳定更新的攒劲资源: >>>点此立即查看<<<

为何必须继承Exception而非其他基类

这源于C#公共语言运行时的底层设计。CLR规定所有可抛出的异常对象类型必须是System.Exception的派生类。

  • Exception是CLR唯一认可的异常根类型。
  • 注意:不推荐继承已被标记为过时的ApplicationException类。
  • 若需体现语义分层,建议继承已有的具体异常类型,如ArgumentExceptionInvalidOperationException

支持序列化的自定义异常最小实现

为确保异常在跨进程通信或日志捕获时不丢失信息,实现序列化支持至关重要。一个健壮的自定义异常通常需要以下四个构造函数:

  • 无参构造函数(供反序列化使用)。
  • 接收(string message)的构造函数。
  • 接收(string message, Exception innerException)的构造函数(用于构建异常链)。
  • 受保护的(SerializationInfo info, StreamingContext context)构造函数(用于序列化兼容)。

标准示例代码如下:

public class InvalidOrderStateException : Exception
{
    public InvalidOrderStateException() { }
    public InvalidOrderStateException(string message) : base(message) { }
    public InvalidOrderStateException(string message, Exception innerException) 
        : base(message, innerException) { }
    protected InvalidOrderStateException(SerializationInfo info, StreamingContext context) 
        : base(info, context) { }
}

如何正确添加额外属性

为异常添加如ErrorCode等额外属性能丰富错误信息,但需注意以下要点:

  • 自定义属性必须在所有构造函数中正确初始化,尤其在反序列化构造函数中需从info读取值。
  • 若附加信息仅用于日志或调试,可优先使用Exception.Data字典属性,它无需修改类结构且自动参与序列化。
  • 避免在异常属性中包含敏感信息(如密码、令牌),以防泄露。

以下为安全添加ErrorCode属性的示例:

public class PaymentFailedException : Exception
{
    public int ErrorCode { get; }

    public PaymentFailedException(int errorCode, string message) 
        : base(message)
    {
        ErrorCode = errorCode;
    }

    protected PaymentFailedException(SerializationInfo info, StreamingContext context) 
        : base(info, context)
    {
        ErrorCode = info.GetInt32(nameof(ErrorCode));
    }

    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue(nameof(ErrorCode), ErrorCode);
        base.GetObjectData(info, context);
    }
}

补充XML注释与序列化特性

为提升代码可维护性和团队协作效率,建议注意以下工程细节:

  • 添加[Serializable]特性以确保自定义序列化逻辑生效(在.NET Framework中为必需,.NET Core/.NET 5+中建议添加)。
  • 为异常类及成员添加XML注释,便于智能提示和生成API文档。
  • 遵循命名约定,异常类名应以“Exception”结尾。
  • 保持异常构造函数轻量,避免在其中执行耗时操作(如IO、网络请求)。

理解异常的本质是关键:异常标志着正常程序流程的中断,其核心职责是清晰传达错误内容、位置及原因,而非执行修复或重试逻辑。

侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述

热游推荐

更多
湘ICP备14008430号-1 湘公网安备 43070302000280号
All Rights Reserved
本站为非盈利网站,不接受任何广告。本站所有软件,都由网友
上传,如有侵犯你的版权,请发邮件给xiayx666@163.com
抵制不良色情、反动、暴力游戏。注意自我保护,谨防受骗上当。
适度游戏益脑,沉迷游戏伤身。合理安排时间,享受健康生活。