c# - 为什么 C# 空条件运算符不适用于 Unity 可序列化变量?
问题描述
我注意到,如果我有一些变量暴露给 Unity 检查器,例如:
[SerializeField] GameObject _tickIcon;
如果我不分配它们并尝试使用 null 条件运算符并在该对象上调用一个方法,我会收到一个异常,指出该变量未分配。所以基本上不是这样做:
_tickIcon?.SetActive(false);
它迫使我这样做:
if(_tickIcon != null)
{
_tickIcon.SetActive(false)
}
所以我猜这一定是unity运行时特有的东西,它不是真的为null,但我可以检查null并且它可以工作。我真的不明白这一点。
解决方案
它通常不适用于继承自的任何东西UnityEngine.Object
!
由于它们在内部实现==
/!=
方法的方式不同,因此绕过了它。请参阅自定义 == 运算符,我们应该保留它吗?
ReSharper 在可能意外绕过底层 Unity 引擎对象的生命周期检查中解释得很好
如果派生自的类型
UnityEngine.Object
使用空合并 (??
) 或空传播或条件 (?.
) 运算符,则会显示此警告。这些运算符不使用在 上声明的自定义相等运算符UnityEngine.Object
,因此绕过检查底层原生 Unity 引擎对象是否已被破坏。为了阐明意图,首选显式null
或布尔比较或调用。System.Object.ReferenceEquals()
UnityEngine.Object
在某些情况下并非如此 null
,但仍保留一些元数据。所以底层object
(= System.Object
)不是null
,UnityEngine.Object
的覆盖==
运算符只是返回true
for == null
。
_tickIcon?.gameObjct
因此,像throw a这样的事情的主要原因NullReferenceException
是?.
操作员只直接在底层工作,object
而UnityEngine.Object
他们的自定义实现在不同的级别上工作。
例如之后
Destroy(_tickIcon);
_tickIcon.SetActive(false);
你会注意到你没有得到一个正常NullReferenceException
的情况,如果它实际上是这种情况,null
而是让一个 Unity 习惯MissingReferenceException
告诉你抛出异常的可能原因。
长话短说:由于解决方案UnityEngine.Object
具有隐式bool
运算符
对象存在吗?
那里给出的例子实际上并不是真的 - 见上文
您应该始终检查是否存在源自以下内容的任何内容UnityEngine.Object
:
if(_tickIcon)
{
_tickIcon.SetActive(false);
}
推荐阅读
- django - Django 媒体图像显示空白框
- ruby-on-rails - 升级到 Rails 6 后:Content-Disposition 标头现在添加了奇怪的文件名*=UTF-8
- azure-cli - 是否有任何系统方法可以找到每个 Azure CLI 命令所需的最低访问权限或角色?
- javascript - 使用 API 渲染数据
- sql - SQL 中的高效(线性时间)嵌套查询
- python - 构建数据矩阵时如何处理“索引越界”?
- anaconda - conda-forge 存储库是否需要 Anaconda 商业版许可证?
- php - Google Big Query insertAll() 返回成功结果,但表为空
- jenkins - 将扩展选择参数值从一个作业传递到 Jenkins 管道中的另一个远程作业
- haskell - 使用 Gloss 时有没有办法让原点位于左上角