在C#的开发场景中,系统自带的异常类型只能覆盖通用的错误情况,当遇到业务特有的错误逻辑时,自定义异常能更精准地传递错误信息,方便后续的问题排查和业务处理。我们可以通过继承Exception类来创建符合自身需求的异常派生类。

自定义异常的基本规则
自定义异常类需要遵循几个基础规范,才能保证和C#的异常处理机制兼容:
- 必须继承自
Exception类或者其子类,通常直接继承Exception即可 - 类名建议以
Exception结尾,符合C#的命名规范,方便其他开发者识别 - 需要包含三个常用的构造函数,分别对应不同的初始化场景
- 如果需要序列化异常对象,还需要实现序列化相关的逻辑,不过基础使用场景下可以暂时忽略
自定义异常类的实现
我们首先来定义一个简单的业务异常类,用于处理用户年龄不合法的场景,这个类会包含三个标准的构造函数:
using System;
namespace CustomExceptionDemo
{
// 自定义年龄异常类,继承自Exception
public class InvalidAgeException : Exception
{
// 无参构造函数
public InvalidAgeException() : base() { }
// 带异常信息的构造函数
public InvalidAgeException(string message) : base(message) { }
// 带异常信息和内部异常的构造函数,用于异常链传递
public InvalidAgeException(string message, Exception innerException) : base(message, innerException) { }
}
}
自定义异常的抛出与捕获
定义好自定义异常之后,我们就可以在业务逻辑中抛出这个异常,然后在调用方进行捕获处理。下面是一个用户年龄校验的示例:
using System;
namespace CustomExceptionDemo
{
public class User
{
private int age;
public int Age
{
get { return age; }
set
{
// 年龄校验逻辑,不符合要求时抛出自定义异常
if (value <= 0 || value > 150)
{
throw new InvalidAgeException($"输入的年龄{value}不合法,年龄必须在1到150之间");
}
age = value;
}
}
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
User user = new User();
try
{
user.Name = "张三";
// 尝试设置不合法的年龄
user.Age = 200;
Console.WriteLine($"用户{user.Name}的年龄是{user.Age}");
}
catch (InvalidAgeException ex)
{
// 捕获自定义异常,输出错误信息
Console.WriteLine($"捕获到自定义年龄异常:{ex.Message}");
}
catch (Exception ex)
{
// 捕获其他通用异常
Console.WriteLine($"捕获到其他异常:{ex.Message}");
}
}
}
}
带自定义属性的异常类
如果我们需要在异常中携带更多的业务信息,还可以在自定义异常类中添加自定义的属性。比如下面的异常类可以携带不合法的年龄值:
using System;
namespace CustomExceptionDemo
{
public class InvalidAgeException : Exception
{
// 自定义属性,存储不合法的年龄值
public int InvalidValue { get; set; }
public InvalidAgeException() : base() { }
public InvalidAgeException(string message) : base(message) { }
public InvalidAgeException(string message, Exception innerException) : base(message, innerException) { }
// 带自定义属性的构造函数
public InvalidAgeException(string message, int invalidValue) : base(message)
{
InvalidValue = invalidValue;
}
}
class Program
{
static void Main(string[] args)
{
try
{
int inputAge = -5;
if (inputAge <= 0 || inputAge > 150)
{
throw new InvalidAgeException($"输入的年龄{inputAge}不合法,年龄必须在1到150之间", inputAge);
}
}
catch (InvalidAgeException ex)
{
Console.WriteLine($"异常信息:{ex.Message},不合法的年龄值为:{ex.InvalidValue}");
}
}
}
}
自定义异常的注意事项
在使用自定义异常时,有几个点需要特别注意:
- 不要过度定义自定义异常,只有系统异常无法覆盖的业务场景才需要自定义,避免异常类泛滥
- 自定义异常的构造函数要和基类保持一致,保证异常可以被正常序列化和传递
- 抛出自定义异常时要携带足够清晰的错误信息,方便后续排查问题
- 捕获异常时优先捕获具体的自定义异常类型,再捕获通用的
Exception类型,避免异常被提前拦截
自定义异常是C#异常处理机制的重要补充,合理使用可以让代码的错误处理逻辑更清晰,也更贴合业务的实际需求。
C#自定义异常Exception派生类C#异常处理自定义异常类修改时间:2026-07-15 04:09:21