null合并运算符赋值给self

Dan*_*ert 6 c# null serialization null-coalescing-operator unity-game-engine

我目前在Unity中设置了两个脚本来处理一些UI音频.一个是经理,另一个是为特定的UI元素播放声音.我所拥有的简化版本如下:

public class AudioUIManager : MonoBehaviour //Only one of these in the scene
{
    public AudioClip genericUISound; //This is set in the inspector.
}
Run Code Online (Sandbox Code Playgroud)
public class AudioUITextAnimation : MonoBehaviour
{
    [SerializeField]
    private AudioClip specifiedUISound; //This is not set in the inspector
    [SerializeField]
    private AudioUIManager audioUIManager; // I get a reference to this elsewhere

    void Start()
    {
        //Use generic sounds from audio manager if nothing is specified.
        specifiedUISound = specifiedUISound ?? audioUIManager.genericUISound;
        print(specifiedUISound);
    }
}
Run Code Online (Sandbox Code Playgroud)

我在这里想要实现的是让该specifiedUISound字段使用在检查器中分配给它的声音.如果未分配声音,则使用UI管理器中的通用声音.这样可以节省我为需要相同声音的数百万个按钮分配相同的声音,但如果我愿意,可以选择为一个按钮设置特定的声音.

然而,在空coalessing算asigning nullspecifiedUISound,即使它是空和audioUIManager的声音是不是.另外,如果我使用三元运算符来检查null,我可以使用它:

specifiedUISound = specifiedUIsound == null ? audioUIManager.genericUISound : specifiedUISound;
Run Code Online (Sandbox Code Playgroud)

我是否误解了空合并运算符?为什么会这样?

编辑: Jerry Switalski指出,只有在specifiedUISound序列化时才会发生这种情况.(如果是public或者它有[SerializeField]属性).任何人都可以了解这里发生的事情吗?

rut*_*ter 11

您正在运行Unity的自定义相等运算符:

当MonoBehaviour有字段时,仅在编辑器中,我们不会将这些字段设置为"真正的空",而是设置为"假空"对象.我们的自定义==运算符能够检查某些东西是否是这些伪空对象之一,并且相应地表现.虽然这是一个奇特的设置,它允许我们将信息存储在假的null对象中,当您在其上调用方法时,或者当您向对象请求属性时,它会为您提供更多上下文信息.如果没有这个技巧,你只会得到一个NullReferenceException,一个堆栈跟踪,但你不知道哪个GameObject有MonoBehaviour,该字段为null.

在编辑器中运行时,Unity会将序列化替换null为实际上不具有的标记值null.这允许他们在某些情况下提供更多信息性错误消息.

specifiedUISound等于null?这取决于你的要求.C#有多个"相等"的概念,包括数据相等和引用相等.

有些检查会说价值相等:==Object.Equals

其他人会说,他们是不相等的:??Object.ReferenceEquals

此行为只会在编辑器中发生.在独立构建中运行时,任何null值都将是null.