Unity C#:自定义对象为null,但我可以访问其属性

Unity C#:自定义对象为null,但我可以访问其属性,c#,unity3d,C#,Unity3d,我在代码中找到了解决这个问题的方法,但我想了解为什么会发生这种情况,因为我想学好C。我搜索了很多,可以简化问题,下面是简化代码: /*MyCustomComponent.cs, this is attached to a game object in the scene*/ using UnityEngine; using System.Collections; using System.Collections.Generic; public class MyCustomComponent :

我在代码中找到了解决这个问题的方法,但我想了解为什么会发生这种情况,因为我想学好C。我搜索了很多,可以简化问题,下面是简化代码:

/*MyCustomComponent.cs, this is attached to a game object in the scene*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class MyCustomComponent : MonoBehaviour {
    void Start () {
        Test testInstance = new Test();
        Debug.Log (testInstance);
        Debug.Log (testInstance == null);
        Debug.Log (testInstance.Equals(null)); //Also tried the same with Equals()
        Debug.Log (testInstance.value);
    }
}

/*Test.cs*/
using UnityEngine;
using System.Collections;

public class Test : Object {
    public int value = 7;
    public Test(){

    }
}
控制台输出:

null
true
7

为什么会这样?一个对象怎么可能为null但返回属性值呢?

因为
Unity.Object
的工作方式非常特殊,基本上它包含有关托管的对象的数据,同时指向本机的对象(简而言之)

让我们举一个例子:您创建了一个从
monobhavior
继承的新对象。现在有两个对象,一个在本机端,另一个在托管端。由于
monobhavior
继承自
Unity.object
,因此您可以访问托管对象的
instanceID
属性。基本上,后者用于在Inspector中显示对象的所有相关数据

现在,您想通过调用相同的命名方法来销毁这个游戏对象。本机对象实际上已销毁,但托管对象未销毁,因为所有托管对象只能由垃圾收集器销毁。正是在这一点上,
Unity.Object
变成了
null
:这是Unity引擎使用的一个技巧,以避免您尝试访问不再存在的本机对象。最终,当GC被调用时,Unity.Object也将被销毁


这就是为什么您不应该创建一个直接从
Unity.object
继承的Unity对象,而应该只从
monobhavior
ScriptableObject
继承。输出返回:null、true、true、7。(我把Equals()行注释掉了,所以当我在这里写它时,我忘了写第二个真值)。如果从
对象继承类,则变量对象为null,但类参数存在。从继承中删除
Object
在此上下文中,必须注意
UnityEngine.Object
不是
System.Object
。后者是C#中所有类的最终祖先,前者有它自己的行为。@MarkBenovsky我认为这应该是一个答案……非常感谢你的答案(它起作用了!)。如果我从Test.cs中删除“:Object”,它将返回:Test(如果条件试图查看它是否为null,则返回false)。不管怎么说,我还是不明白为什么在执行testInstance=new UnityEngine.Object();//或者:newsystem.Object();它返回null而不是Object。(当条件询问其是否等于null时,它也返回true)非常感谢,我再次阅读了所有回复以及UnityEngine.Object()和System.Object()文档,现在已经清楚了。=)我的错误是,我试图从System.Object继承,但我使用的是“Object”(即UnityEngine.Object)。