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

C#中断言失败时如何抛出异常?是否有内置等效方法?

有没有内置方法让断言失败时抛出异常,而非继续执行?

问题描述

我最近开始在代码里用断言,但发现Debug.Assert和Trace.Assert在条件不满足的时候还会继续执行代码。我想找一个内置的等效方法,能在条件不满足时直接抛出异常,这样就能避免代码在意外状态下继续跑了,还是说我得自己实现这个逻辑?

编辑补充:我的代码大概是这样的,这段代码用于处理PUT请求,目的是更新现有资源(理想情况下用Id标识,如果之前有部分保存的情况就用GUID标识)。如果是保存新资源,必须确保提供了GUID:

public int Save(Guid? personGuid, Person person) {
    if (person.Id > 0) {
        Update(person);
    }
    Trace.Assert(personGuid.HasValue);
    SaveToDb(personGuid, person);
}

注:已经勾选了Define TRACE常量选项。


解决方案

其实.NET里没有直接开箱即用的“断言失败就抛异常”的方法——毕竟Debug.Assert和Trace.Assert的设计初衷是调试时给出提示,而非直接终止执行抛出异常。不过有几种简单的方案可以实现你要的效果,根据你的场景选就行:

1. 自己写个轻量的断言工具类(最推荐,灵活可控)

这其实花不了几分钟,写个静态类就能搞定,还能完全控制异常类型、错误信息,甚至可以指定只在Debug模式生效:

public static class MyAssert
{
    // 加[Conditional("DEBUG")]就只在Debug模式下触发,去掉的话Release也会生效
    [Conditional("DEBUG")]
    public static void IsTrue(bool condition, string errorMessage = "断言失败:不符合预期状态")
    {
        if (!condition)
        {
            // 这里可以根据业务场景换更合适的异常类型,比如ArgumentException、InvalidOperationException等
            throw new InvalidOperationException(errorMessage);
        }
    }
}

然后你的代码改成这样就行:

public int Save(Guid? personGuid, Person person) {
    if (person.Id > 0) {
        Update(person);
    }
    MyAssert.IsTrue(personGuid.HasValue, "保存新资源时必须提供有效的GUID");
    SaveToDb(personGuid, person);
}

这个方案的好处是完全贴合你的需求,而且可以根据项目需要扩展更多断言方法(比如NotNull、IsInstanceOfType之类的)。

2. 自定义TraceListener让Trace.Assert抛异常

如果你不想自己写工具类,想复用Trace.Assert的语法,可以全局替换Trace的监听器,让它在断言失败时抛出异常:

public class ExceptionThrowingTraceListener : TraceListener
{
    public override void Write(string message) { }
    public override void WriteLine(string message) { }
    
    public override void Fail(string message)
    {
        throw new InvalidOperationException($"断言失败:{message}");
    }
    
    public override void Fail(string message, string detailMessage)
    {
        throw new InvalidOperationException($"断言失败:{message},详情:{detailMessage}");
    }
}

然后在程序启动的地方(比如Program.cs)添加这个监听器:

// 先清空默认的监听器,避免同时弹出对话框或者输出日志
Trace.Listeners.Clear();
Trace.Listeners.Add(new ExceptionThrowingTraceListener());

这样所有的Trace.Assert失败时都会抛出异常了,不过这个是全局生效的,适合整个项目都需要这个行为的场景。

3. 直接写条件判断抛异常(最直观,适合业务强制校验)

如果你的场景是不管Debug还是Release都必须校验的业务逻辑,直接写条件判断反而更清晰,不用绕弯子:

public int Save(Guid? personGuid, Person person) {
    if (person.Id > 0) {
        Update(person);
    }
    if (!personGuid.HasValue)
    {
        throw new InvalidOperationException("保存新资源时必须提供有效的GUID");
    }
    SaveToDb(personGuid, person);
}

这种方式没有额外的依赖,别人看代码一眼就能明白这里的校验逻辑,适合那些不能跳过的关键业务检查。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 22:07:35