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

.NET 9泛型方法中T.CreateChecked未抛出溢出异常的疑问

泛型方法中T.CreateChecked未触发预期的OverflowException

我尝试在泛型方法中用T.CreateChecked检查算术溢出,但它的行为让我困惑——就算是明确应该抛出异常的场景,也没有抛出。

示例1:符合预期抛出异常

short a = 32767;
short b = 32767;

short.CreateChecked(a + b); // <-- 抛出System.OverflowException: 算术运算导致溢出。

示例2:已溢出但未抛出异常

short a = 32767;
short b = 32767;

short result = GenericChecked<short>(a, b);

T GenericChecked<T>(T a, T b) where T : INumber<T>
{
    return T.CreateChecked(a + b); // 未抛出异常,反而返回-2。
}

进一步测试:相加最大值仍未抛出

_ = GenericChecked<short>(a, b);

T GenericChecked<T>(T a, T b) where T : INumber<T>, IMinMaxValue<T>
{
    return T.CreateChecked(T.MaxValue + T.MaxValue);
}

为什么T.CreateChecked(a + b)不能和short.CreateChecked(a + b)表现一致?明明是相同的算术运算,却没有抛出OverflowException?

测试环境:.NET 9


解答

问题核心在于泛型方法中a + b的运算逻辑:

在非泛型的示例1中,a + b是两个short类型相加,超出short范围后CLR会直接截断数值得到-2,随后short.CreateChecked接收这个截断值,检测到它是溢出运算的结果,因此抛出异常。

但在泛型方法里,当T实现INumber<T>时,a + b默认执行无溢出检查的算术运算——也就是直接截断溢出部分得到合法的T类型值(比如-2),此时T.CreateChecked接收的是一个符合T类型范围的合法值,自然不会触发溢出检查。

CreateChecked的设计目的是将超出T范围的外部值转换为T时检查溢出,而非验证传入的T类型值是否来自溢出运算。泛型场景中a + b已经完成了无检查运算,得到的是合法T实例,所以CreateChecked不会抛出异常。

要在泛型中实现带溢出检查的加法,应该使用INumber<T>提供的AddChecked方法,它会在运算过程中直接检测溢出:

T GenericChecked<T>(T a, T b) where T : INumber<T>
{
    return T.AddChecked(a, b); // 此时会正确抛出OverflowException
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:50:13