对接收空引用的扩展方法使用条件空运算符能否触发警告?
针对可空扩展方法被条件空运算符绕过场景的检查方案
原生Roslyn默认规则、ReSharper开箱即用的检查规则中,暂无直接匹配该场景的校验项,你可以通过以下几种方式实现自定义警告:
方案1:自定义Roslyn代码分析器
你可以开发轻量级的Roslyn分析器,匹配满足以下全部条件的代码节点,触发自定义警告:- 调用表达式使用了
?.条件空运算符 - 调用的目标方法是扩展方法
- 该扩展方法的第一个
this参数被标记为可空(即可空引用类型后缀?,或标注[AllowNull]特性)
分析器的实现逻辑非常轻量,仅需扫描语法树的条件访问节点,匹配语义即可,部署后可在全项目编码、编译阶段触发告警。
- 调用表达式使用了
方案2:ReSharper结构化搜索自定义规则
如果你使用ReSharper/Rider,可以通过内置的结构化搜索功能快速配置自定义检查:- 打开ReSharper的「结构化搜索」功能,新建搜索模式
- 输入搜索模板:
$instance$?.$extensionMethod$($args$) - 为
$extensionMethod$添加约束:类型为扩展方法,且其第一个this参数为可空类型 - 将该规则的告警级别设置为警告,保存后即可在编码阶段实时检测匹配场景。
方案3:单元测试扫描管控
如果不想改动开发工具链,也可以通过单元测试做批量校验:- 自定义标记特性如
[NullHandledExtension],给所有自身处理了null入参的扩展方法添加该标记 - 编写单元测试扫描项目中所有调用了带该特性扩展方法的代码,检查是否使用了
?.运算符,匹配到则单元测试报错。
- 自定义标记特性如
注意:按照C#语言设计,扩展方法本质是静态方法,
instance?.Extension()的语法逻辑本身就是先判断instance是否为null,为null直接跳过调用返回null,和扩展方法本身是否支持null入参无关,因此该场景不属于通用编译错误,默认不会触发告警。
内容的提问来源于stack exchange,提问作者Mike Nunan
相关产品推荐
相关产品推荐

