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


相关推荐: Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】  laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程  瓜子二手车官方网站在线入口 瓜子二手车网页版官网通道入口  Zeus浏览器网页版官网入口 宙斯浏览器官网在线通道  Python企业级消息系统教程_KafkaRabbitMQ高并发应用  Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】  如何撰写建站申请书?关键要点有哪些?  Android仿QQ列表左滑删除操作  javascript基本数据类型及类型检测常用方法小结  如何为不同团队 ID 动态生成多个非值班状态按钮  Laravel模型事件有哪些_Laravel Model Event生命周期详解  如何挑选最适合建站的高性能VPS主机?  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  Laravel如何发送系统通知?(Notification渠道示例)  北京专业网站制作设计师招聘,北京白云观官方网站?  Laravel如何使用Passport实现OAuth2?(完整配置步骤)  Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例  Laravel中Service Container是做什么的_Laravel服务容器与依赖注入核心概念解析  Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践  如何用PHP快速搭建CMS系统?  高配服务器限时抢购:企业级配置与回收服务一站式优惠方案  实例解析Array和String方法  大型企业网站制作流程,做网站需要注册公司吗?  Laravel如何创建自定义Facades?(详细步骤)  Windows10如何删除恢复分区_Win10 Diskpart命令强制删除分区  米侠浏览器网页背景异常怎么办 米侠显示修复  Linux安全能力提升路径_长期防护思维说明【指导】  长沙企业网站制作哪家好,长沙水业集团官方网站?  Laravel如何使用Gate和Policy进行权限控制_Laravel权限判定与策略规则配置  Windows10如何更改计算机工作组_Win10系统属性修改Workgroup  打造顶配客厅影院,这份100寸电视推荐名单请查收  Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权  百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧  制作公司内部网站有哪些,内网如何建网站?  Win11怎么开启自动HDR画质_Windows11显示设置HDR选项  怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?  Laravel如何实现多级无限分类_Laravel递归模型关联与树状数据输出【方法】  利用python获取某年中每个月的第一天和最后一天  JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)  非常酷的网站设计制作软件,酷培ai教育官方网站?  敲碗10年!Mac系列传将迎来「触控与联网」双革新  Laravel N+1查询问题如何解决_Eloquent预加载(Eager Loading)优化数据库查询  Laravel如何配置中间件Middleware_Laravel自定义中间件拦截请求与权限校验【步骤】  Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】  如何快速登录WAP自助建站平台?  Laravel怎么为数据库表字段添加索引以优化查询  如何利用DOS批处理实现定时关机操作详解  Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】  如何基于云服务器快速搭建个人网站?  linux写shell需要注意的问题(必看)