为什么 C# 空条件运算符不适用于 Unity 可序列化变量? [英] Why does C# null-conditional operator not work with Unity serializable variables?

查看:39
本文介绍了为什么 C# 空条件运算符不适用于 Unity 可序列化变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've noticed that if I have some variables exposed to the Unity inspector such as:

[SerializeField] GameObject _tickIcon;

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

If I leave them unassigned and try to use the null conditional operator and call a method on that object I get an exception saying the variable is not assigned. So basically instead of doing this:

_tickIcon?.SetActive(false);

这迫使我这样做:

if(_tickIcon != null)
{
   _tickIcon.SetActive(false)
}

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

So I'm guessing this must be something specific to unity's runtime, it's not really null, but I can check for null and it work. I don't really understand this.

推荐答案

它通常不适用于从 UnityEngine.Object!

由于他们在内部实现了 ==/!= 方法的不同,它被绕过了.参见 自定义 == 操作符,我们是否应该保留它?

It is bypassed due to how they internally implemented the ==/!= method differently. See Custom == operator, should we keep it?

ReSharper 在 可能意外绕过底层 Unity 引擎对象的生命周期检查

ReSharper explained it pretty well in Possible unintended bypass of lifetime check of underlying Unity engine object

如果从 UnityEngine.Object 派生的类型使用空值合并 (??) 或空值传播或条件 (?.) 运算符.这些运算符不使用在 UnityEngine.Object 上声明的自定义相等运算符,因此绕过检查以查看底层原生 Unity 引擎对象是否已被破坏.为了阐明意图,最好使用显式的 null 或布尔比较,或者调用 System.Object.ReferenceEquals().

This warning is shown if a type deriving from UnityEngine.Object uses either the null coalescing (??) or null propagation or conditional (?.) operators. These operators do not use the custom equality operators declared on UnityEngine.Object, and so bypass a check to see if the underlying native Unity engine object has been destroyed. An explicit null or boolean comparison, or a call to System.Object.ReferenceEquals() is preferred in order to clarify intent.

UnityEngine.Object 在某些情况下 不是真的 null 但仍然保留一些元数据.所以底层的object( = System.Object) 是not nullUnityEngine.Object 被覆盖的 == 操作符只为 == null 返回 true.

UnityEngine.Object is in some occasions not really null but still keeps some meta data. So the underlying object( = System.Object) is not null, UnityEngine.Object's overwritten == operator just returns true for == null.

因此诸如 _tickIcon?.gameObjct 之类的东西抛出 NullReferenceException 的主要原因是 ?. 运算符仅直接作用于底层objectUnityEngine.Object 在不同级别上与他们的自定义实现一起工作.

The main reason why therefore things like _tickIcon?.gameObjct throw a NullReferenceException is that the ?. operator only directly works on the underlying object while the UnityEngine.Object works with their custom implementation on a different level.

例如之后

Destroy(_tickIcon);
_tickIcon.SetActive(false);

你会注意到你没有得到一个正常的 NullReferenceException,如果它实际上是 null 就会出现这种情况,而是得到一个 Unity 海关 MissingReferenceException 告诉您引发异常的可能原因.

you will note that you don't get a normal NullReferenceException which would be the case if it were actually null but rather get a Unity customs MissingReferenceException telling you a probable reason for why the exception was thrown.

长话短说:作为解决方案 UnityEngine.Object 具有隐含的 bool 运算符

Long story short: As solution UnityEngine.Object has the implicit bool operator

对象是否存在?

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

您应该始终检查是否存在从 UnityEngine.Object 派生的任何内容,如下所示:

You should always check the existence of anything derived from UnityEngine.Object like this:

if(_tickIcon)
{
    _tickIcon.SetActive(false);
}

这篇关于为什么 C# 空条件运算符不适用于 Unity 可序列化变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆