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

C#集合索引操作中!、!?运算符的含义及运行时行为是什么?

C# 空容忍运算符与条件访问组合使用相关解答

以下解答基于C# 8及以上版本的可空引用类型上下文环境,你提供的代码默认开启了可空引用类型检查。

1. 集合后、索引前!运算符的含义

这里的!是空容忍(null-forgiving)运算符,属于编译期静态分析用的后缀运算符。作用是显式告诉编译器:你确定当前修饰的表达式(这里是testList)在运行时一定不为null,要求编译器跳过对该表达式的空值警告检测。
无论后面是否接?运算符,!的作用范围都仅限于它前面紧邻的表达式(这里就是testList本身),不会影响后续的索引访问逻辑。

2. 编译器对!?组合的解析规则

!?并不是C#定义的独立组合运算符,编译器会按照后缀运算符优先级从高到低拆分解析:

  • 后缀!(空容忍运算符)的优先级高于后缀?[](条件索引访问运算符)
  • 因此testList!?[3]会被编译器解析为 (testList!)?[3]
    1. 第一步先处理testList!:将原本可能标记为可空的List<int>?类型的testList,标记为非空的List<int>类型
    2. 第二步对第一步得到的非空List<int>执行条件索引访问?[3],最终返回值类型为int?,和你观察到的变量y的类型一致。

3. 空容忍运算符的运行时行为与空值触发结果

  • 空容忍运算符是纯编译期特性,运行时会被完全忽略,不会注入任何额外的检查或处理逻辑,仅用于抑制编译器的空值警告。
  • 若运行时testList实际为null:
    • 对于testList![4]:等价于直接对null执行索引访问,会抛出NullReferenceException异常
    • 对于testList!?[3]:等价于对null执行条件索引访问,?[]检测到左操作数为null时会直接返回null,不会抛出异常,最终y的取值为null。

4. !?与?的运行时等价性判断

是的,二者运行时行为完全等价。
因为!在运行时没有任何实际作用,testList!?[3]的运行时逻辑和testList?[3]完全一致。二者的区别仅存在于编译期:加!会抑制编译器对testList可能为null的警告输出,不加则会在testList被标记为可空时触发编译警告。


内容的提问来源于stack exchange,提问作者Abhijith C R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 18:27:06