Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# GetComponent returning";空";而不是空值_C#_Unity3d - Fatal编程技术网

C# GetComponent returning";空";而不是空值

C# GetComponent returning";空";而不是空值,c#,unity3d,C#,Unity3d,如果请求的组件未附加到对象,我对GetComponent的返回值感到困惑。根据Unity文档,GetComponent应该返回null。但是,GetComponent返回的是请求类型的“null”对象,而不是值null 在本例中,我的游戏对象没有附加CircleCollider2D。当我在CircleCollider2D x=GetComponent()行上设置断点时, 为什么返回的值不是空的 编辑: 另一编辑: 可能是Unity重载了=操作符,使得GetComponent始终返回一个对象,但

如果请求的组件未附加到对象,我对
GetComponent
的返回值感到困惑。根据Unity文档,
GetComponent
应该返回null。但是,
GetComponent
返回的是请求类型的“null”对象,而不是值
null

在本例中,我的游戏对象没有附加
CircleCollider2D
。当我在
CircleCollider2D x=GetComponent()行上设置断点时,

为什么返回的值不是空的

编辑:

另一编辑:

可能是Unity重载了
=
操作符,使得
GetComponent
始终返回一个对象,但是该对象可以有一个内部“null”状态,与
null
相比,该状态返回true?我可以在
UnityEngine
名称空间中看到以下声明

public static bool operator ==(Object x, Object y);
public static bool operator !=(Object x, Object y);

GetComponent
应返回“Component
类型的对象”。因此,它不应返回“null”,而应返回~null
值。也许应该向unity3d报告这种奇怪的行为,

似乎
GetComponent()
没有返回TRUE
null
。相反,它返回带有默认值的新T,当使用任何空字段时,会触发
MissingComponentException
GetInstanceID()
GetHashCode()
之所以有效,是因为它们只使用设置为默认值0的
int m_InstanceID
。不确定
ToString()
如何工作,但当
m_InstanceID==0
时,它可能返回
“null”

证明:

void Start()
    {
        CircleCollider2D getComponent = GetComponent<CircleCollider2D>();
        CircleCollider2D empty = null;
        CircleCollider2D newCC = new CircleCollider2D();
        Debug.LogFormat("getComponent.GetInstanceID() {0}", getComponent.GetInstanceID());
        Debug.LogFormat("newCC.GetInstanceID() {0}", newCC.GetInstanceID());
        try
        {
            Debug.LogFormat("empty.GetInstanceID() {0}", empty.GetInstanceID());
        }
        catch (System.NullReferenceException e)
        {
            Debug.Log("empty.GetInstanceID() doesnt work, im true null");
        }
        try
        {
            string t = getComponent.name;
        }
        catch (System.Exception e)
        {
            Debug.Log(string.Format("getComponent fires {0} when any field is null", 
                e.ToString()));
        }
        try
        {
            string t = newCC.name;
        }
        catch (System.Exception e)
        {
            Debug.Log(string.Format("newCC fires {0} when any field is null",
                e.ToString()));
        }
    }
此外:

为什么
getComponent==null
为真?通常只是:

`getComponent.GetInstanceID() == otherComponent.GetInstanceID()`
o==null
情况下:

return !(
o.GetCachedPtr() != IntPtr.Zero || (!(o is MonoBehaviour) && 
!(o is ScriptableObject) &&
Object.DoesObjectWithInstanceIDExist(o.GetInstanceID())));
所以我猜InstanceID=0的对象永远不存在。 如果您想了解更多信息,请搜索反编译的UnityEngine/UnityEngine/Object.cs

可能是Unity重载了==运算符吗

Tldr:

为什么返回值不为null

根据:

当MonoBehavior具有字段时,仅在编辑器中,我们不设置 这些字段被设置为“真空”,但被设置为“假空”对象

为什么??根据该条,基本上有两个原因:

  • 在编辑器模式下:获取有关调用的更多上下文信息,因此如果出现异常,您将能够知道是哪个对象导致了异常

  • 来自UnityEngine.Object的每个对象
都包装在一个C#对象中,以保留对Unity C/C++GameEngine对象的引用。在编辑器/代码中,我们使用C元素,但这些只是对“真实”C++对象的引用。现在,显式地处理那些“真实”C++对象的生命周期(如果你是代码>破坏<代码>某个C++对象,它将被破坏,分配的内存将被释放),但是当垃圾回收器决定释放该内存时,C对象将被完全销毁。因此,你将有一个不为零的C++对象指向一个空C++对象。使用这个假null技巧,你会知道这个特定的C对象是<代码> null <代码>,因为在C++端它被破坏了。p>
如果您有一个单例并且
if(sm_Instance==null)
未按预期工作,则这一点也很重要,您可以使用:
if(EqualityComparer.Default.Equals(sm_Instance,null))
instad

编辑:如果您的单例使用泛型,并且您的类型约束为
class

public class Singleton<T> where T : class {

相关线程:


Ps:如果您转到UnityEngine.Object程序集,您将能够看到重载:

快结束了


然而,似乎发生的是GetComponent返回的是请求类型的“null”对象,而不是null值。
您是如何得出这个结论的?请向我们展示您的代码-如果不看代码,就不可能给您提供好的建议。代码就是
CircleCollider2D x=GetComponent()我的
唤醒方法中有它。我在那一行上放了一个断点,屏幕截图是在跨过那一行后从Locals窗口中显示的。
x.GetType()
返回什么?说真的,你在问题中添加的代码越多,这个过程就变得容易多了。
CircleCollider2D
是结构还是类?你能给我们看一下它的源代码吗(也许是通过反编译的)?有帮助吗?是的,Unity论坛上的答案确实有帮助。我很高兴看到这是我想要的行为,我没有发疯。谢谢。实际上
default(IntPtr)=IntPtr.Zero
所以
o.GetCachedPtr()==IntPtr.Zero
我怀疑这种“奇怪的行为”实际上是故意的。
return !(
o.GetCachedPtr() != IntPtr.Zero || (!(o is MonoBehaviour) && 
!(o is ScriptableObject) &&
Object.DoesObjectWithInstanceIDExist(o.GetInstanceID())));
public class Singleton<T> where T : class {
public class Singleton<T> where T : UnityEngine.Object {