Search code examples
c#unity-game-engineif-statement

is not null Vs != null (Unity C#)


The only difference (besides the syntax) is, that the compiler guarantees that no user-overloaded operator is called when using is not null instead of != null (or is null instead of == null).

According to these explanations, there should be no difference between the two

But when I use the Unity engine with Json data I see a functional difference that Is Not null doesn't recognize Jason as empty, but it recognizes the same data as empty when I check it with !=

What is the reason for this?

Maybe there is something wrong, sorry (the translator is used)

I expected a null value to be detected with both conditions


Solution

  • I expected a null value to be detected with both conditions

    Yes, true null values are detected by both operators. However, Unity is a bit special. Unity is a C++ engine, and when it comes to memory management, there are some major issues. In C# you can not destroy any object manually as this is completely in the hand of the garbage collector. References to objects can not suddenly become null in C#.

    Since native (C++) objects in Unity can be destroyed at any time, this creates an issue with the C# scripting layer. A GameObject or other Component reference can not magically become null. So Unity uses a trick. They have overloaded the == operator and the Equals method, and when comparing dead objects to null, those will return true. This is called a fake null object. It's still a valid C# object, but it can no longer be used because the actual native object was destroyed. Most built-in components and classes in Unity are just C# wrapper classes which have a native object behind the scenes. (Every class derived from UnityEngine.Object)

    That means you can not use the is null or any of the null coalescing operators on variables with a type that is derived from UnityEngine.Object. When those references are truly null, it would work. However in most cases you would encounter a fake null object and an is null check would not see this as null since it's still an instance.

    There was a blog post about the == operator overload about 10 years ago. Here is Unity's reference source and the custom == operator. As you can see it actually calls CompareBaseObjects and when the object is dead, it will "fake" that it is null.

    Many say this was a bad decision, however that decision was made when the only operator that does a direct null check was ??. In the recent years C# got many operators which also bypass operator overloading so it becomes a growing issue. However getting rid of the overload would mean you always would have to do an additional IsAlive check manually because you can't get rid of the fundamental clash between the C++ and C# world.