C#中能否为泛型T添加Null-conditional运算符??支持版本是多少
问题解答
可行性结论
- 该写法完全可行,
Compare(T x, T? y)的签名可以清晰表达「x不可为空、y允许为空」的约定,符合C#可空性注释的设计规范。 - 该语法从C# 9.0版本开始正式支持。
详细规则说明
C#对泛型参数使用?修饰符的支持分两个阶段:
- C# 8.0引入可空引用类型(NRT)时,仅允许对有明确类型约束的泛型参数使用
?修饰符:要么约束为where T : class(引用类型),要么约束为where T : struct(值类型)。无任何约束的泛型T直接写T?会触发编译错误。 - C# 9.0扩展了该语法的适用范围,无约束的泛型
T也可以直接用T?修饰:- 当实际传入的
T是引用类型时,T?代表对应可空引用类型 - 当实际传入的
T是值类型时,T?自动等价于Nullable<T>
完全覆盖你提到的「T既可以是引用类型也可以是值类型」的使用场景。
- 当实际传入的
补充注意:要让该可空约定生效,需要在项目配置中开启可空引用类型检查(在.csproj文件中添加
<Nullable>enable</Nullable>配置项),否则编译器不会识别T?的可空注释,也不会给出对应的空安全校验提示。
低版本兼容方案
如果需要兼容C# 9.0以下的版本,可以用AllowNull特性实现等价效果:
int Compare(T x, [AllowNull] T y)
该写法在C# 8.0及以上版本均可生效,同样能明确表达y参数允许为null的约定。
内容的提问来源于stack exchange,提问作者Zenith
相关产品推荐
相关产品推荐

