谜之UnityEngine.Object
问题代码示例
public Transform Parent = null; void Start () { //Transform Parent = null; Transform SelfTransform = GetComponent<Transform>(); Transform a = Parent ?? SelfTransform; Transform b = Parent != null ? Parent : SelfTransform; Debug.Log(a == b); //返回False }
//public Transform Parent = null; void Start () { Transform Parent = null; Transform SelfTransform = GetComponent<Transform>(); Transform a = Parent ?? SelfTransform; Transform b = Parent != null ? Parent : SelfTransform; Debug.Log(a == b); //返回True }
初步解释
That specific operator only takes the usual ‘null’ into account, whereas Unity also offers a pseudo-null object to present more information to the programmers in the editor (that’s what happens in the second example, it’ll set such a mysterious object to that non-assigned, serialized field).
Usual comparisons like ==, != and some boolean comparisons will check whether the variable references ‘null’ or that pseudo-null.
public Transform Parent; void Start() { // overriden operator compares to null and fake-null, result is true Debug.Log(Parent == null); // casting to a System.Object reveals that there's actually something assigned to it, result is false Debug.Log((System.Object)Parent == null); }
可以看到虽然在Inspector里Parent是none,但是其实它是指向了某个pseudo-null的实例对象,也就是说编辑器里看到的空并不是真正的null
结论:
Never check if a UnityEngine.Object is null directly, always use the bool operator
Never cast a UnityEngine.Object to a System.Object
Never write a generic method designed to take UnityEngine.Object and System.Object
Never use ?? on a UnityEngine.Object
引用:
http://qiankanglai.me/2016/10/21/fake-null/
https://blogs.unity3d.com/2014/05/16/custom-operator-should-we-keep-it/