'A value is null, but the check returns otherwise?

EDIT: This explains everything! - Unity creates managed fake wrappers around your UnityEngine.Objects when you destroy them. That means if you destroy a UEObject, the C# wrapper could still be not null. The == is implemented in a custom way so that when you destroy a UEObject checking == null will return true. This obviously doesn't play well with generics.


This is literally driving me insane. I have this method right here:

public static void AssertNotNullAfterAssignment<T>(ref T value, Func<T> get, string msg) where T : class
{
    if (value == null)
        value = get();
    if (value == null)
        throw new NullReferenceException(msg);
}

I'm calling it on a reference that is null at the start:

AssertNotNullAfterAssignment(ref fovMeshFilter, GetComponent<MeshFilter>, "fovMeshFilter");

What's really insane, is that the check if (value == null) is returning false! even though the value IS null!

Here's a short video I made showing this.

What's interesting though, if I copy/paste the method code to the method I used it in (in OnEnable) it works (pretty much what I have commented in OnEnable in the video)

So... it works if it was outside the assertion method, but not inside. I also tried Equals instead of == but the same.

Anybody has any idea what's going on?

Edit: Here's OnEnable, the method I'm calling the assertion from:

private void OnEnable()
{
    //if (fovMeshFilter== null)
    //  fovMeshFilter= GetComponent<MeshFilter>();
    //if (fovMeshFilter== null)
    //  throw new NullReferenceException("fovMeshFilter");

    AssertNotNullAfterAssignment(ref fovMeshFilter, GetComponent<MeshFilter>, "fovMeshFilter");
}

If I use the uncommented lines it works as expected, but the assertion method doesn't work for some only-god-knows-why reason.

Edit1: What we have here?

enter image description here

Edit2:

enter image description here

Edit3:

So after the great help from this awesome community, and couple of tests I came to the solution. I could have sworn it was one of the very first things I tried! you must believe me! XD - It was just to use .Equals instead of == - Like @Edin shows in his answer, doing a == on a generic object seem to call System.Object's == - But, calling .Equals should always resolve to the correct overload of Equals. I don't know why is it this way, I mean, why don't the '==' also resolve to the correct overload?



Solution 1:[1]

vexe, in your video, when you mouse over value you see it is null, but you also see a little triangle to the left of it, as if you can expand it. Did you try expanding it? Because you don't get that triangle when mouse overing the null itself. Maybe its not null, but its an object, with a .toString() returning null.

edit

I think your object is NOT null. And that your debugger is failing to show you the correct value. (Hence the exception in your screenshot.) Try doing someting like var foo = value.mesh; inside your called function, and debug on that one instead.

It seems as though this object is not so breakpoint/watch friendly.

Solution 2:[2]

Thanks for the answer. I was trying this:

 public bool IsDisabled()
{
    Debug.Log("in is disabled check and my image name is " + myImage.sprite.name  +"i return="+ (myImage.sprite == Disabled));
    return (myImage.sprite==Disabled);
       
}

The debug log would return false but the return value would be true. Then I used

return (myImage.sprite.Equals(Disabled));

and it worked fine. Really strange since I am not deleting any gameobjects.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Dimitris Kiourtsoglou