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

Unity中为何null变量同时满足==null与is BoxExit判断?

Unity中"假Null"引发的矛盾判定解析

核心原因:Unity对MonoBehaviour子类重写了==运算符

你遇到的问题本质是Unity的"假Null"机制:对于继承自MonoBehaviour的类(比如你的BoxExit),Unity重写了==运算符和null判定逻辑。当一个MonoBehaviour对象被Destroy()销毁、或者其所在GameObject被禁用/销毁时,Unity会让== null返回true,但这个对象在CLR(公共语言运行时)层面并没有真正变为null——它仍然保留着完整的类型信息,只是被Unity标记为"无效对象"。

所以你的代码里:

  • mirr == null:Unity判定这个BoxExit实例已无效,返回true
  • mirr is BoxExit:CLR检查对象的实际类型,确认它确实是BoxExit的实例,返回true
    这就导致两个条件同时成立,执行了var a = 1;的代码。

为什么string的例子结果不同?

你测试的string aa = null;是真正的CLR Null:此时变量aa在CLR中没有指向任何对象,自然不存在类型信息,所以aa is string返回false。这和Unity的"假Null"完全是两回事——Unity的"假Null"是CLR层面仍存在的对象,只是被Unity标记为无效。

如何区分真假Null?

如果要判断一个MonoBehaviour对象是否是真正的CLR Null,可以使用object.ReferenceEquals()方法(这个方法不会被Unity重写):

if (object.ReferenceEquals(mirr, null))
{
    // 这里才是真正的Null,不会出现is BoxExit为true的情况
}

另外,C#的is null语法也是基于CLR层面的判定,所以:

if (mirr is null)
{
    // 真正的CLR Null才会进入这里
}

额外说明

你的currentEntrance是IEntrance接口类型,而BoxExit实现了该接口同时继承自MonoBehaviour。当你把一个被Unity标记为无效的BoxExit实例赋值给这个接口变量时,Unity的==重写逻辑依然会生效(因为实际对象是MonoBehaviour子类),但is运算符会直接检查对象的实际类型,所以出现了看似矛盾的结果。

内容的提问来源于stack exchange,提问作者vainquit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 16:03:28