Testing for null, bug or feature?

Hi there,

I’ve noticed that if I have an object which inherits from UnityEngine.Object, and it gets destroyed and so becomes null, the following happens:

Debug.Log( myObject ); // Outputs "null"

if( myObject == null )
{
   // This code doesn't run?
}

if( !myObject )
{
   // But this code does
}

So testing for null explicitly doesn’t work, presumably this is because there is actually an object there, but it has to behave as if it is null.

Now, I don’t like using the if( !myObject ) test, I think it’s bad practice. Even so, for the particular code I’m writing now I actually can’t use that, as I’m working with System.Object instances which may or may not also be UnityEngine.Object instances.

So, is this a bug, or a feature?

Edit: This code will very quickly show the problem I’m talking about:

using UnityEngine;

public class NewBehaviourScript : MonoBehaviour 
{
    private System.Object go;
    private System.Object t;

    public void Start()
    {
        GameObject temp = new GameObject( "go" );
        this.go = temp;
        this.t = temp.transform;

        Destroy( temp );
    }

    public void Update()
    {
        Debug.Log( this.go == null );
        Debug.Log( this.t == null );
    }
}

UnityEngine.Object overrides Equals(). The null-coalescing operator (??) also doesn’t work. It’s just the way Unity works. This forum thread has a deeper discussion on the issue.

I can’t reproduce this behaviour. Is it possible that you use Destroy and test the object reference in the same frame? The object is destroyed the next frame…

If you wait at least one frame or use DestroyImmediate it works as expected

    var GO = new GameObject("Test");
    Debug.Log("GO == null: " + (GO == null));
    Debug.Log("GO != null: " + (GO != null));
    Debug.Log("!GO: " + (!GO));
    Debug.Log("GO == false: " + (GO == false));
    Debug.Log("GO != false: " + (GO != false));
    GameObject.Destroy(GO);
    yield return null;
    Debug.Log("Destroy");
    Debug.Log("GO == null: " + (GO == null));
    Debug.Log("GO != null: " + (GO != null));
    Debug.Log("!GO: " + (!GO));
    Debug.Log("GO == false: " + (GO == false));
    Debug.Log("GO != false: " + (GO != false));

This gives me:

GO == null: False
GO != null: True
!GO: False
GO == false: False
GO != false: True
Destroy
GO == null: True
GO != null: False
!GO: True
GO == false: True
GO != false: False