Can object constructor return a null?

前端 未结 5 997
伪装坚强ぢ
伪装坚强ぢ 2020-12-30 19:32

We have taken over some .NET 1.1 Windows Service code that spawns threads to read messages off a queue (SeeBeyond eGate JMS queue, but that is not important) and in turn spa

5条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-30 19:49

    As core mentions, operator overloading can make it appear that a constructor returned null, when that's not what really happened. The authors of the article core found say they haven't seen it used, but it actually is used in a very popular product: Unity.

    This will compile and log a message at run time:

    using UnityEngine;
    
    public class Test:MonoBehaviour
    {
        void Start()
        {
            AudioSource as = new AudioSource();
    
            if (as == null)
            {
                Debug.Log("Looks null to me.");
            }
        }
    }
    

    Now, the fault here is mine, because one should not call the AudioSource constructor directly. But one should know that the == operator is overloaded at the root of the inheritance tree for the objects Unity can reference. Here's what the Unity manual says about UnityEngine.Object's == operator:

    Be careful when comparing with null.

    e.g.

    GameObject go = new GameObject();
    Debug.Log (go == null); // false
    
    Object obj = new Object();
    Debug.Log (obj == null); // true
    

    Instatiating a GameObject adds it to the scene so it's completely initialized (!destroyed). Instantiating a simple UnityEngine.Object has no such semantics, so the(sic) it stays in the 'destroyed' state which compares true to null.

    While instantiating a GameObject initializes it, instantiating an AudioSource object doesn't, so the comparison with null returns true.

    This unusual idiom is made even more stealthy by virtue of the fact that attempts to reference properties of the uninitialized AudioSource object will throw null-reference exceptions, which I initially misinterpreted as meaning the object reference was null, not the property.

    Others have answered the OP's question, but I wanted to add this answer because the OP's code might actually make sense if the Thread class therein isn't the one we would expect it to be, just as Object (and its descendants) isn't quite what you might expect it to be in a Unity script (that is, it is actually UnityEngine.Object, rather than System.Object, which gets you the overloaded == operator that so confused me).

提交回复
热议问题