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

如何告知.NET编译器:经合并的可空int变量已不为null?

C# 可空类型赋值后类型推断问题

我写了下面这个C#方法:

public int Add(int? a, int? b) {
    a ??= 0;
    b ??= 0;
    return a + b;
}

最后一行会报错:Cannot implicitly convert type 'int?' to 'int'。

我知道可以通过两种方式修复:

  • 显式强制转换:return (int)(a + b);
  • 对每个操作数再次做空合并:return (a ?? 0) + (b ?? 0);

我的疑问是:有没有办法让编译器知道,既然我们已经通过空合并把变量都设为0了,后续可以把它们当作int而非int?来处理?

举个TypeScript的例子,下面的代码能正常运行,因为编译器能识别到最后一行时a和b都是number类型,而非number | undefined:

const add = (a?: number, b?: number): number => {
  // 此时a和b都是number | undefined类型
  a ??= 0; // a现在是number类型
  b ??= 0; // b现在是number类型
  return a + b; // 返回值是number,不是number | undefined
}

解答

C# 目前不支持这种自动的类型窄化逻辑:虽然a ??= 0确保了运行时a绝不会为null,但变量的编译时类型依然是int?,所以a + b的结果还是int?,无法隐式转换为int。

TypeScript的类型系统在这类赋值操作上有更精细的类型推断能力,能跟踪变量的类型变化,但C#的可空值类型设计中,这种赋值操作不会改变变量的静态类型。

除了你提到的两种修复方式,还有更直观的替代方案:直接将可空变量赋值给非可空的新变量,让编译器明确类型:

public int Add(int? a, int? b) {
    int aVal = a ?? 0;
    int bVal = b ?? 0;
    return aVal + bVal;
}

或者使用GetValueOrDefault()方法,效果和空合并一致:

public int Add(int? a, int? b) {
    return a.GetValueOrDefault() + b.GetValueOrDefault();
}

内容的提问来源于stack exchange,提问作者Benjamin U.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:57:09