C# is not null模式匹配方法 C#如何简化null检查

发布时间 - 2026-02-02 00:00:00    点击率:
is not null 是 C# 8.0 起语义更清晰、支持流分析的 null 检查方式,优于 != null;适用于方法体内局部变量判断,可与类型模式组合用于 switch,但不能替代 ?? 或泛型约束。

is not null 模式匹配替代传统 != null

从 C# 8.0 开始,

is not null 是语义更清晰、编译器推断更友好的 null 检查方式。它不只是语法糖,还能触发可空引用类型(NRT)的流分析,让后续代码中变量的可空性状态被正确识别。

  • if (obj is not null) 后,编译器知道 obj 在该分支内非空,不会报 CS8602(可能为 null 的解引用)
  • 相比 obj != null,它在模式匹配上下文中更自然,比如和 switch 或嵌套模式一起用
  • 注意:仅当项目启用 enable 且目标框架支持(.NET Core 3.0+ / .NET 5+)时,才能发挥完整效果

switch 中结合 is not null 做类型 + 非空联合判断

单独检查 null 很常见,但更多时候你真正想表达的是“如果是某个类型,且不为 null,就执行某逻辑”。这时候把 is not null 和类型模式组合起来,比先判空再强制转型更安全简洁。

object input = GetSomething();
switch (input)
{
    case string s when s.Length > 0: // s 已知非 null,Length 可直接调
        Console.WriteLine($"非空字符串: {s}");
        break;
    case int i:
        Console.WriteLine($"整数: {i}");
        break;
    case null: // 注意:null 是一个独立 case,必须显式写
        Console.WriteLine("输入为 null");
        break;
    default:
        Console.WriteLine("其他类型");
        break;
}
  • case string s 本身就隐含了非 null 判断(因为 string 是引用类型,模式匹配成功即表示非 null)
  • 如果写 case string? s,则 s 可能为 null,后续访问需再检查
  • case null 必须显式列出,否则 null 会掉进 default 分支

避免误用:别在泛型约束或属性初始化里硬套 is not null

is not null 是运行时模式匹配操作符,不能替代编译期约束或静态保证。强行在不合适的地方用,要么报错,要么失去意义。

  • ❌ 不能用于泛型约束:where T : not null 是错误写法;正确是 where T : class(引用类型)或 where T : notnull(C# 9 新关键字,注意拼写是 notnull,无空格)
  • ❌ 不要在字段/属性初始化器中依赖它做非空保证:private readonly string _name = _input is not null ? _input.Name : "unknown"; —— 若 _input 是字段,初始化顺序可能导致未定义行为
  • ✅ 它最适合用在方法体内、明确有值可判断的局部变量或参数上

对比 ??is not null:用途完全不同

有人看到 is not null 就想替掉所有 null 合并操作符 ??,这是误解。两者解决的问题不在同一维度。

  • ?? 是提供默认值的表达式,关注“取什么”,例如:var name = user?.Name ?? "Anonymous"
  • is not null 是条件判断,关注“做什么”,例如:if (user is not null) { user.LogIn(); }
  • 混用反而啰嗦:if (user is not null) { Process(user); }if (user != null) { Process(user); } 更推荐;但 user?.Name ?? "N/A" 绝对不该改成 (user is not null ? user.Name : "N/A") —— 前者简洁、短路、可读性强

真正容易被忽略的是:即使启用了可空引用类型,编译器也不会自动把 != null 升级为 is not null 的流分析能力。你得主动改写,并确保上下文中有足够的类型信息供编译器推理。


# switch  # c#  # .net  # String  # NULL  # if  # 局部变量  # class  # 引用类型  # private  # 泛型  # var  # default  # 的是  # 会报  # 能为  # 更清晰  # 体内  # 是一个  # 这是  # 还能  # 做什么  # 中有 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Python高阶函数应用_函数作为参数说明【指导】  移动端脚本框架Hammer.js  Laravel如何处理文件下载请求?(Response示例)  Laravel如何实现API资源集合?(Resource Collection教程)  网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?  jimdo怎样用html5做选项卡_jimdo选项卡html5实现与切换效果【指南】  Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】  Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】  Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】  个人摄影网站制作流程,摄影爱好者都去什么网站?  悟空浏览器如何设置小说背景色_悟空浏览器背景色设置【方法】  Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】  如何在宝塔面板中修改默认建站目录?  Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】  悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音  如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?  JS去除重复并统计数量的实现方法  HTML 中动态设置元素 name 属性的正确语法详解  Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载  Laravel如何使用Blade组件和插槽?(Component代码示例)  英语简历制作免费网站推荐,如何将简历翻译成英文?  如何快速查询网站的真实建站时间?  Laravel如何从数据库删除数据_Laravel destroy和delete方法区别  HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】  EditPlus中的正则表达式 实战(4)  Laravel如何使用Collections进行数据处理?(实用方法示例)  Laravel 419 page expired怎么解决_Laravel CSRF令牌过期处理  如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】  详解Android——蓝牙技术 带你实现终端间数据传输  百度输入法ai组件怎么删除 百度输入法ai组件移除工具  Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧  如何彻底卸载建站之星软件?  宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法  Linux安全能力提升路径_长期防护思维说明【指导】  JS实现鼠标移上去显示图片或微信二维码  Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】  Bootstrap CSS布局之列表  Thinkphp 中 distinct 的用法解析  用v-html解决Vue.js渲染中html标签不被解析的问题  如何在阿里云完成域名注册与建站?  html5audio标签播放结束怎么触发事件_onended回调方法【教程】  Laravel怎么上传文件_Laravel图片上传及存储配置  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  zabbix利用python脚本发送报警邮件的方法  Laravel Seeder怎么填充数据_Laravel数据库填充器的使用方法与技巧  Laravel用户密码怎么加密_Laravel Hash门面使用教程  如何确保西部建站助手FTP传输的安全性?  Laravel怎么判断请求类型_Laravel Request isMethod用法  香港网站服务器数量如何影响SEO优化效果?  中国移动官方网站首页入口 中国移动官网网页登录