- Home /
How UnityEngine handle that if statement if(referencType)
Hi Everyone,
If you create an reference type instance like
public LocalMissionManager localMissionManager;
and if you check it like
if(localMissionManager)
//bla bla bla
I observe that it behave like
if(localMissionManager != null)
//Bla bla bla
If I delete using unityengine it is not executed.
How unity handle that and is my observation correct ? is it checking if its null or not ?
Answer by Kishotta · Apr 13, 2020 at 09:48 PM
It depends on what the LocalMissionManager
looks like.
If it is a POCO, then the null value will evaluate to false.
If it is a MonoBehaviour
or other UnityEngine object derivative, there is some weird stuff with how the c# interfaces with C++ (the reason you can't new
a MonoBehaviour
) and so null checking doesn't really work. Unity compares the object to some special "null" object (I'm afraid I'm not too familiar with the details), so it doesn't work as you'd expect.
That's actually wrong. C# does not allow an implicit or explicit type conversion to bool like that is the case with C or C++. If you try this
object o = new object();
if (o)
{
}
You get an error "CS0266" that there's no implicit type conversion from object to bool. It tells you that an explicit conversion does exist and if you're missing a cast.
The following does compile but would not work at runtime / would throw an InvalidCastException:
object o = new object();
if ((bool)o)
{
}
Just looking at the generated IL code the "bool cast" is just an "unbox" instruction which of course will fail since the object is not a boxed value type.
C# does not have an implicit conversion of "null"--> false and "not null" --> true.
However C# allows a class / type to implement custom type conversion operators. This is what UnityEngine.Object did. The custom bool conversion operator implementation does check if the object is actually null or if it's a fake null object.
If you have never heard about fake null objects I highly recommend to read this blog post
To sum up the most important things: Every UnityEngine.Object derived type has two parts, the managed C# object and the native C++ object. The two parts live in completely seperate worlds and memory ranges. $$anonymous$$any UnityEngine.Object derived types are just empty wrapper objects. So they do not contain any data and barely methods with managed code. All those objects just have an instance ID and a cached pointer to the native object. When such an object is destroyed (with Destroy or through internal engine code) the cached pointer will be set to null. However the managed C# wrapper object can not be destroyed since it lives in managed memory. Therefore if the native part is destroyed / not present the managed wrapper pretends it is null.
Hmm that make sense. Thank you for your answer and blog post, I guess I got main purpose as "Since we do a lot of extra security / safety / usage checks in the editor to make your life easier, at the expense of some performance." blog says. Also I got how unity handle Unirtengine.Objects in background with c++ and c#.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Renderer on object disabled after level reload 1 Answer
How to make custom Inspectors for serialized classes 2 Answers