尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

别用“设计感”掩盖无知:从一次 null == 0 的事故说起

别用“设计感”掩盖无知:从一次 null == 0 的事故说起
📅 发布时间:2026/6/20 12:06:05

那天下午,我盯着一行再普通不过的代码,足足愣了三分钟:

if (value.Equals(null))
{// 这行居然执行了?!
}

value 是一个 Value 类型的对象,构造时传入的是整数 0——它明明不是 null。调试器里字段正常,内存地址也清清楚楚。可 .Equals(null) 却返回了 true。这已经不是“奇怪”了,这是在挑战我对编程语言的基本信任。

带着一丝不安,我点进了 Value.Equals:

public class Value : XXObject, IObject
{public override bool Equals(object obj){return base.Equals(obj);}
}

哦,它自己没实现,直接甩锅给父类 XXObject。那就继续追

public class XXObject : IObject
{public override bool Equals(object? obj){return XXEquals.Equals(_value, obj);}
}

看到这里,我心里咯噔一下:
为什么一个 Equals 要委托给静态类?
为什么 Value 和 XXObject 都要实现同一个接口 IObject?
感觉就是过度抽象+静态工具滥用

但 debug 不能停。我硬着头皮点进 XXEquals.Equals,眼前出现了一段堪称“史诗级轮子”的 switch 大法:

public static new bool Equals(object value, object? obj)
{if (obj is IObject _obj){return Equals(value, _obj.GetValue());}switch (value){case int v:{return obj switch{byte v2 => v == v2,short v2 => v == v2,// ... 省略一堆类型_ => v == XXConvert.ToInt(obj)};}
}

问题就出在最后那个兜底分支:XXConvert.ToInt(obj)。
当 obj 是 null 时,它居然没有抛异常,而是.....返回了 0?

我颤抖着手点进去:

public static int ToInt(object? obj, int def = default)
{return ToIntNull(obj) ?? def;
}

而 def 的默认值是 default(int),也就是 0。
所以 ToInt(null) → ToIntNull(null) 返回 null → ?? 0 → 最终得到 0。

于是整个链条闭环了:

  • value.Equals(null)
  • → XXEquals.Equals(0, null)
  • → 0 == XXConvert.ToInt(null)
  • → 0 == 0
  • → true

那一刻,我悬着的心终于死了:

这不是 bug,这是一个自以为“通用”的轮子,在用一套看似合理实则荒谬的逻辑,系统性地践踏语言最基本的契约。

值得庆幸的是,在 .NET(C# 7.0+)中,我们不需要依赖可能被重写的 Equals 或 == 来判断 null。
官方早已提供了一种语义明确、无法被篡改的 null 检查方式

if (value is null)
{// 安全!这永远只检查引用/实例是否为 null
}

所以,即使底层有人造了“null 转 0”的轮子,只要上层用 is null,就能免疫这类静默错误。

但这只是“止血”,不是“治病”。

虽然 is null 能让我们暂时避开陷阱,但问题的根源依然存在

别用“设计”掩盖无知

说实话,看到 XXConvert.ToInt(null) 返回 0 的那一刻,我气笑了。

不是因为代码复杂,而是因为这种设计透露出一种令人不安的傲慢:

“我知道用户可能会传 null,但我不想让他们处理异常——我替他们‘智能’地处理成默认值。”

听起来很贴心?不,这是对语义的背叛。

在几乎所有主流编程语言中,null 都代表“无值”、“缺失”、“未初始化”。而 0 是一个明确的、有效的值。把“无”等同于“零”,就像把“没人来开会”理解成“来了一个人,他叫张三,职位是 0 号员工”一样荒谬。

更可怕的是,这种“智能”被包装在三层抽象之下:

  • 接口 IObject(看似规范)
  • 基类 XXObject(看似复用)
  • 静态工具类 XXEquals + XXConvert(看似解耦)

结果呢?解耦不解祸,封装不封错。
所有调用者都被蒙在鼓里,直到某天某个 if (obj.Equals(null)) 突然走错分支,系统在静默中走向崩溃。


这件事让我意识到:
所谓专业,不是你会造多复杂的轮子,而是你清楚哪些边界绝不能碰——比如相等性、空值语义、类型安全这些设计底线。

在这个行业,最昂贵的轮子,从来不是重复造的,而是造歪了还装上车的。

相关新闻

  • AI训练素材与数据集供应商推荐:卓特视觉的专业解决方案
  • 2025年国内靠谱的AGV货架生产厂家推荐榜单,立体货架/重载货架/中型货架/组合式货架/流利式货架/背网货架AGV货架批发厂家推荐榜单
  • 2025年长沙公务员面试机构排行榜:前五强揭晓,湖南长沙公务员面试排行优质品牌选购指南

最新新闻

  • 电力市场预测:基础模型与任务特定模型的性能效率权衡
  • NXP Real-time Edge嵌入式Linux系统构建实战:基于Yocto的实时边缘计算平台开发指南
  • UVa 543 Goldbach‘s Conjecture
  • 批量修改XML文件名与内容的Bash脚本实践
  • 星野来信赋能:苏州短视频广告投流的3大核心策略与5步精准优化法,湖州市短视频广告投流机构 - 品牌推荐师
  • 中卫市2026年黄金回收本地靠谱白银回收+铂金回收门店指南 优选门店汇总及电话地址推荐 - 大熊猫898989

日新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号