现代 C# 开发:简化自定义异常

发布: (2025年12月21日 GMT+8 05:00)
3 min read
原文: Dev.to

Source: Dev.to

Introduction

错误是不可避免的。有时它们很简单,有时又非常特定于你的业务领域。C# 提供了许多内置异常,但它们并不总能完整地说明问题。自定义异常可以让你清晰地传达领域特定的问题。

When to Use a Custom Exception

考虑一个订单系统,用户尝试下单却违反了业务规则。

throw new InvalidOperationException("User cannot place this order");

内置异常可以工作,但信息过于通用。自定义异常则提供了更多上下文:

throw new OrderNotAllowedException(userId);

Defining a Basic Custom Exception

自定义异常只是继承自 Exception 的类。

public class OrderNotAllowedException : Exception
{
    public OrderNotAllowedException(string message)
        : base(message)
    {
    }
}

这个最小版本已经足以开始使用。

Adding Contextual Information

与其把所有信息都塞进消息字符串,不如将相关数据暴露为属性。

public class OrderNotAllowedException : Exception
{
    public Guid UserId { get; }

    public OrderNotAllowedException(Guid userId)
        : base($"User {userId} is not allowed to place an order")
    {
        UserId = userId;
    }
}

现在日志和错误处理程序可以直接访问 UserId,无需解析字符串,从而简化调试。

.NET Version Considerations

在较旧的 .NET 版本(例如 .NET Framework 4.x 及更早)中,通常需要为序列化添加额外的构造函数。使用现代 .NET(Core、5+、6+、7+)时,上面展示的简单类已经足够。

Avoid Overusing Custom Exceptions

自定义异常很有用,但也可能被滥用。请尽量避免:

  • 将异常用于普通的控制流
  • 创建非常通用且没有实际价值的自定义异常
  • 在公共 API 中暴露内部异常细节

如果内置异常已经能够很好地描述问题,优先使用它。

Guideline Checklist Before Creating a Custom Exception

  1. 这是否代表一个真正的异常情况?
  2. 它是否比简单的消息字符串提供了更多意义?
  3. 名称是否能清晰描述问题?

如果以上三个问题的答案都是 ,那么自定义异常是合适的选择。

Conclusion

自定义异常是一个小功能,却能让你的代码更加清晰、易于维护。恰当地使用它们,可以简洁地说明出错的原因和具体情形。

Back to Blog

相关文章

阅读更多 »