It does not work in general with anything inheriting from UnityEngine.Object
!
It is bypassed due to how they internally implemented the ==
/!=
method differently. See Custom == operator, should we keep it?
ReSharper explained it pretty well in Possible unintended bypass of lifetime check of underlying Unity engine object
This warning is shown if a type deriving from
UnityEngine.Object
uses either the null coalescing (??
) or null propagation or conditional (?.
) operators. These operators do not use the custom equality operators declared onUnityEngine.Object
, and so bypass a check to see if the underlying native Unity engine object has been destroyed. An explicitnull
or boolean comparison, or a call toSystem.Object.ReferenceEquals()
is preferred in order to clarify intent.
UnityEngine.Object
is in some occasions not really null
but still keeps some meta data. So the underlying object
(= System.Object
) is not null
, UnityEngine.Object
‘s overwritten ==
operator just returns true
for == null
.
The main reason why therefore things like _tickIcon?.gameObjct
throw a NullReferenceException
is that the ?.
operator only directly works on the underlying object
(System.Object
) while the UnityEngine.Object
works with their custom implementation on a different level.
E.g. after
Destroy(_tickIcon);
_tickIcon.SetActive(false);
you will note that you don’t get a normal NullReferenceException
which would be the case if it were actually null
but rather get a Unity customs MissingReferenceException
telling you a probable reason for why the exception was thrown.
Long story short: As solution UnityEngine.Object
has the implicit bool
operator
Does the object exist?
The example given there is actually not really true – see above
You should always check the existence of anything derived from UnityEngine.Object
like this:
if(_tickIcon)
{
_tickIcon.SetActive(false);
}