What happens when we create a Monobehavior object using the "new" keyword?!

Hi All,

I know we shouldn’t create any monobehavior objects using the new keyword, but I was working on someone’s code that create an object with new keyword, and I faced a very strange behavior.

first of all when we created an object from a monobehavior class like this:

Test t = new Test();

If you check the “t” object it is just a null, which is a very strange behavior, I think there is no way in C# to get a null reference for the object that has been created using new keyword and constructor, but this is just the beginning of the journey :frowning:

Although the reference is null, but you can call any function from this reference, it will be executed without throwing a null reference exception :hushed:

t.func();

And the most weird part is that if you try to check the “this” reference inside the function, you will find it is a null.

class Test:MonoBehaviour
{
    public void func()
    {
        Debug.Log("Hello from the function" );
        if(this == null)
        {
            Debug.Log("I'm not Exist" );
        }
        else
        {
            Debug.Log("I'm alive");
        }
    }
}

calling the previous function from the t object will print:

Hello from the function
I'm not Exist

What I was trying to do is getting a reference to the function (using delegate) and add it to the OnClick event invocation list of a button dynamically

 UnityAction action = new UnityAction(t.func);
  button.onClick.AddListener(action);

And there is no need to say that the action has a Method but its Target is null which prevent calling the function when the event fire.

I know how to solve my problems, I shouldn’t inherit from Monobehavior, but What I really want to know is that “What happens under the hood?!” I think all the previous behaviors violate the C# standards!

2986113–222231–MonobehaviorCreationTest.rar (25.6 KB)

It’s not really null. Unity has overridden the == and != operators for components with regards to null checks (among a few other more obscure purposes), which is how you can use a (x != null) to see if a Unity component has been destroyed. I think this override should explain all of the weirdness you see. If you used ReferenceEquals(x, null), you should see the expected result.

1 Like

Unity overrode the equality operator to do a custom null check which takes into account whether or not the object has been destroyed. Off the top of my head, using the ctor and not AddComponent bypasses some hooks into the engine that facilitate this custom functionality.

1 Like