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

Unity C#布尔OR语句一侧为真时整体仍返回false问题求解

问题原因
  • 本质是C#运算符重载静态绑定机制和Unity自定义null逻辑的冲突:
    1. Unity只在UnityEngine.Object基类(所有GameObject、组件、脚本资源的父类)上重载了==/!=运算符,实现“对象调用Destroy后与null比较返回true”的特殊规则。实际上被销毁对象的托管堆实例并未立即回收,只是引擎侧原生对象已被释放。
    2. 你的buildable变量是IBuildable接口类型,编译器编译接口类型的==比较时,无法确认实例一定继承自UnityEngine.Object,因此不会绑定Unity重写的运算符,只会执行原生引用相等判断。这种场景下被销毁的对象不是真null,buildable == null实际运行返回false,不会触发||的短路逻辑。
  • 调试窗口显示结果和实际运行不符是IDE调试器的特殊处理导致:Rider、VS等工具的调试器识别到Unity对象实例时,会自动套用Unity的null规则计算表达式,因此你看到监视窗口里buildable == null为true、完整条件返回true,但这和最终编译执行的IL逻辑不一致。
  • 后续执行buildable.BuildingComplete时,访问已销毁的Unity对象成员会触发引擎的缺失引用处理,返回false,最终导致整个属性返回结果不符合预期。
修复方案

禁止直接对接口类型变量使用==null判断Unity对象的销毁状态,先将其转换为UnityEngine.Object类型再执行Unity规则下的空判断,参考代码如下:

public override bool IsFinished
{
    get
    {
        if (buildable is UnityEngine.Object unityObj)
        {
            // 确认是Unity引擎对象,走自定义空判断
            if (unityObj == null) return true;
            return buildable.BuildingComplete;
        }
        // 非Unity对象执行常规空判断
        return buildable == null || buildable.BuildingComplete;
    }
}

如果IBuildable的所有实现类都确定继承自UnityEngine.Object,可以直接简化为:

public override bool IsFinished
{
    get
    {
        return (buildable as UnityEngine.Object) == null || buildable.BuildingComplete;
    }
}

最佳实践:可以封装一个Unity对象的通用扩展方法做判空,统一处理接口、泛型类型的空判断场景,避免同类运算符绑定错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 21:15:48