null coalescing operator assignment to self

这一生的挚爱 提交于 2019-12-05 06:00:31
rutter

You're running into Unity's custom equality operator:

When a MonoBehaviour has fields, in the editor only, we do not set those fields to “real null”, but to a “fake null” object. Our custom == operator is able to check if something is one of these fake null objects, and behaves accordingly. While this is an exotic setup, it allows us to store information in the fake null object that gives you more contextual information when you invoke a method on it, or when you ask the object for a property. Without this trick, you would only get a NullReferenceException, a stack trace, but you would have no idea which GameObject had the MonoBehaviour that had the field that was null.

While running in the editor, Unity replaces your serialized null with a sentinel value that isn't actually null. This allows them to provide more informative error messages in some circumstances.

Is specifiedUISound equal to null? That depends on how you ask. C# has multiple notions of "equality", including data equality and reference equality.

Some checks will say the values are equal: == and Object.Equals

Others will say they are not equal: ?? and Object.ReferenceEquals

This behavior will only occur in the editor. When running in a standalone build, any null values will just be null.

It is not really complete answer to your question and very intresting example, but I ran few tests, and it looks like the problem is in SerializeField attribute.

When I run this (someObj is assigned from inspector nullObj is left empty):

    public AudioClip someObj;

    [SerializeField]
    private AudioClip nullObj;

    void Start () 
    {
        Debug.Log("nullObj == null : " + (nullObj == null));
        Debug.Log("someObj == null : " + (someObj == null));

        nullObj = nullObj ?? someObj;

        Debug.Log ("nullObj == null : " + (nullObj == null));
    }

I have this prints:

However getting rid of SerializeField attribute, makes things work as intended:

    public AudioClip someObj;

    private AudioClip nullObj;

    void Start () 
    {
        Debug.Log("nullObj == null : " + (nullObj == null));
        Debug.Log("someObj == null : " + (someObj == null));

        nullObj = nullObj ?? someObj;

        Debug.Log ("nullObj == null : " + (nullObj == null));
    }

gives:

So reasuming:

I don't really know the root of the problem, but what is fact is that Unity3D serializing fields breaks null coalescing operator in Mono engine. I still don't know how, but maybe just due to changing == operator of seriazlized type??

Anyway I hope it helps at least a little bit.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!