Implicit bool conversion for UnityEngine.Object class, when is null issue.

When I was learning Unity recently, some of the group friends posted the Unity title as follows:

 

At that time, I thought that this question would be tested again with the DestroyImmediate() method and the Destroy() method, but I found that it was too underestimated.

It is not difficult to see that this question mainly examines the conditional judgment of the four if statements.

I also just learned that UnityEngine.Object can be implicitly converted to bool, on the source code:

Line 343 defines how Object implicitly converts bool, so what are the conversion rules?

I'm testing in three cases here:

    private void Start()
    {
        UnityEngine.GameObject obj = new UnityEngine.GameObject();
        Destroy(obj);
        if (obj)
            Debug.Log("obj==true");
        else
            Debug.Log("obj==false");

        UnityEngine.GameObject obj0 = new UnityEngine.GameObject();
        DestroyImmediate(obj0);
        if (obj0)
            Debug.Log("obj0==true");
        else
            Debug.Log("obj0==false");

        UnityEngine.GameObject obj1 = null;
        if (obj1)
            Debug.Log("obj1==true");
        else
            Debug.Log("obj1==false");
    }

The result is as follows:

This also reflects the difference between the DestroyImmediate() method and the Destroy() method

The Object instance still exists for a short time after Destroy, and the Object will be destroyed immediately after DestroyImmediate (false null is involved here, which I will mention later).

So the value of the implicit conversion bool is whether the Object instance exists.

The first if answer is true

Lines 340 and 341 define the overloading of Object ==, != operations. I still test in three cases:

    private void Start()
    {
        UnityEngine.GameObject obj = new UnityEngine.GameObject();
        Destroy(obj);
        Debug.Log(obj is null);
        Debug.Log(obj == null);
        Debug.Log("-------------------------------------------");
        UnityEngine.GameObject obj0 = new UnityEngine.GameObject();
        DestroyImmediate(obj0);
        Debug.Log(obj0 is null);
        Debug.Log(obj0 == null);
        Debug.Log("-------------------------------------------");
        UnityEngine.GameObject obj1 = null;
        Debug.Log(obj1 is null);
        Debug.Log(obj1 == null);
    }

The result is as follows:

It's a strange phenomenon, why are each of the three situations different from each other?

The first case is easy to understand, after all, the Object object has not been destroyed for the time being. . . The latter two cases have been studied. 

Later, I found that UnityEngine.Object has a "false null" status by checking the information:

The UnityEngine.Object class overloads the operation with == and != to make (obj0 == null) true when (obj0 is null) is false.

Therefore, it can be speculated that obj0 is not really null after DestroyImmediate, and I still have doubts when obj0 is really null, and I hope you can give me some advice.

So the second and third if conditions are false, true.

As a side note, in C# throwing away overloaded operators a == null and a is null are exactly equivalent.

The last one: System.Object is the object class, so UnityEngine.Object also inherits from System.Object.

Since System.Object does not have ==, != overloads, then (System.Object)go == null can be equivalent to go is null.

So the fourth if condition is false.

Final test:

    private void Start()
    {
        string s = string.Empty;
        var go = new UnityEngine.GameObject();
        UnityEngine.Object.DestroyImmediate(go);
        if (!go) s += "A";
        if (go is null) s += "B";
        if (go == null) s += "C";
        if ((System.Object)go == null) s += "D";
        UnityEngine.Debug.Log(s);
    }

Test Results:

The result is correct. 

It is the first time to write an article, and I am inexperienced. If there are any deficiencies, you are welcome to correct me.

Tags: Unity

Posted by bluetonic on Wed, 31 Aug 2022 03:49:27 +0930