如何告知.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.
相关产品推荐
相关产品推荐

