为什么 C# 空条件运算符不适用于 Unity 可序列化变量?

use*_*950 5 c# serialization unity-game-engine

我注意到,如果我有一些变量暴露给 Unity 检查器,例如:

[SerializeField] GameObject _tickIcon;
Run Code Online (Sandbox Code Playgroud)

如果我让它们未分配并尝试使用 null 条件运算符并在该对象上调用方法,我会收到一个异常,说明未分配变量。所以基本上不是这样做:

_tickIcon?.SetActive(false);
Run Code Online (Sandbox Code Playgroud)

这迫使我这样做:

if(_tickIcon != null)
{
   _tickIcon.SetActive(false)
}
Run Code Online (Sandbox Code Playgroud)

所以我猜这一定是特定于 Unity 运行时的东西,它不是真正的 null,但我可以检查 null 并且它可以工作。我真的不明白这一点。

der*_*ugo 8

它通常不适用于继承自UnityEngine.Object!

由于他们在内部实现==/!=方法的方式不同,所以它被绕过了。参见自定义 == 运算符,我们应该保留它吗?

ReSharper 在可能意外绕过底层 Unity 引擎对象的生命周期检查中很好地解释了这一点

Object在某些情况下不是真的,null但仍然保留一些元数据。

例如之后

Destroy(_tickIcon);
_tickIcon.SetActive(false);
Run Code Online (Sandbox Code Playgroud)

你会注意到你没有得到一个正常的NullReferenceException,如果它实际上是这种情况,null而是得到一个 Unity 习惯MissingReferenceException告诉你抛出异常的可能原因。


由于解决方案UnityEngine.Object具有隐式bool运算符

对象是否存在?

给出的例子实际上并不是真的 - 见上文

您应该始终检查是否存在这样的派生UnityEngine.Object

if(_tickIcon)
{
    _tickIcon.SetActive(false);
}
Run Code Online (Sandbox Code Playgroud)