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
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.