Null-conditional / Null-Coalescing operators ( ‘?.’ and ‘??’ ) cannot currently be used on serialized fields.
When deserializing a MonoBehaviour, all unreferenced fields are not set to null, instead it references a object with a == operator overload, so it results true when testing for null (when in fact it is not a null reference).
This leads to some unexpected behaviors like:
public class TestBehaviour : MonoBehaviour
{
UnityEngine.GameObject reference;
void Start() {
if (reference?.transform == null) {
Debug.Log("It works!"); // This line is printed as expected
}
}
}
But changing the reference to public changes the execution path
public class TestBehaviour : MonoBehaviour
{
public UnityEngine.GameObject reference;
void Start() {
if (reference?.transform == null) { // throws an exception
Debug.Log("Not executed"); // This line is not reached
}
}
}
Exception:
UnassignedReferenceException: The variable reference of TestBehaviour has not been assigned.
You probably need to assign the reference variable of the TestBehaviour script in the inspector.
This null reference behaviour was probably created to help developers when trying to access unassigned references, where it would print the attribute name inside the exception, but this ‘helper’ is now causing an UnassignedReferenceException where it should not exist.
The ?? operator also does not work as expected on that scenario.
var validReference = optionalReference ?? referencedAtribute;
The code above would always store ‘optionalReference’ on ‘validReference’, regardless if ‘optionalReference’ is set or not.
My opinion:
this pretty UnassignedReferenceException only works when trying to access a Serialized Object attribute, so the user is not safe from NullReferenceExceptions.
- It tries to solve a ‘problem’ that is not Unity’s fault (out of its domain)
- It helps only on some specific scenarios
- It creates other problems with it
Basically not worth it.
What should companies do to avoid such weird bugs? Recommend its developers to not use ‘?.’ and ‘??’ at all? (yes I’ve heard that).
At least give me the option to read attributes as null, when they are not referenced on Unity editor.