Null 引用
Understand what causes a NullReferenceException in C# and how to avoid uninitialized object references.
阅读时间4 分钟最后更新于 1 个月前
尝试访问值为 的类型的成员时,C# 中会发生 。在运行时出现 通常意味着在使用对象引用变量之前忘记初始化该变量。有关产生 null 引用的常见编码错误的完整解释,请参阅 Microsoft 文档。
nullNullReferenceExceptionNullReferenceExceptionNull 引用错误消息如下所示:
NullReferenceException: Object reference not set to an instance of an object at Example.Start () [0x0000b] in /Unity/projects/nre/Assets/Example.cs:10
此错误消息指出脚本文件 的第 10 行发生 ,该异常发生在 函数内部。根据这些信息,比较容易查找和修复 Null 引用异常。在此示例中,代码为:
Example.csNullReferenceExceptionStart()using UnityEngine;using System.Collections;public class Example : MonoBehaviour { // Use this for initialization void Start () { GameObject myGameObject = GameObject.Find("exampleGameObject"); Debug.Log(myGameObject.name); } }
代码会查找名为“exampleGameObject”的游戏对象。在此示例中不存在该名称的游戏对象,因此 函数返回 。在下一行(第 9 行),我们使用 变量并尝试打印出其引用的游戏对象的名称。由于 Unity 正在尝试访问不存在的游戏对象,因此会返回
Find()nullmyGameObjectNullReferenceExceptionNull 检查
此示例中的解决方案是,在给定名称的游戏对象不存在的情况下包含结果。以下脚本将检查 变量是否返回 ,如果是,则显示一条消息:
gonullusing UnityEngine;using System.Collections;public class Example : MonoBehaviour { void Start () { GameObject myGameObject = GameObject.Find("exampleGameObject"); if (myGameObject == null) { Debug.Log("No GameObject called exampleGameObject found"); } else { Debug.Log(myGameObject.name); } } }
自定义 == 运算符
对于继承自 UnityEngine.Object 的类型,Unity 使用 C# 相等和不等运算符的自定义版本。这意味着,即使 在技术上持有有效的 C# 对象引用,上述示例 () 中的 null 检查也可以对 求值(反过来, 也可以对 求值)。在以下两种情况下会发生这种情况:
myGameObjectmyGameObject == nulltruemyGameObject != nullfalse- 对象可以是所谓的“假 null”或占位对象,Unity 在编辑器中仅用于填充未初始化的 MonoBehaviour 字段。这些对象可存储有用的调试信息,以便在您尝试引用这些字段时帮助您找到这些字段的来源。
- 对象可以是托管 (C#) 对象,该对象尚未进行垃圾收集,但由于非托管 (C++) 对应对象已被销毁,因此应被视为 null。
Try/Catch 代码块
如果使用需要在检视面板 (Inspector) 窗口中初始化的变量,Unity 也会调用 。如果忘记这样做,则变量将为 。处理 的另一种方法是使用 / 代码块。例如:
NullReferenceExceptionnullNullReferenceExceptiontrycatchusing UnityEngine;using System;using System.Collections;public class Example2 : MonoBehaviour { public Light myLight; // set in the inspector void Start () { try { myLight.color = Color.yellow; } catch (NullReferenceException ex) { Debug.Log("myLight was not set in the inspector"); } } }
在此代码示例中,名为 的变量是需要在检视面板窗口中设置的 。如果未设置此变量,则默认为 。
myLightLightnull若尝试在 代码块中改变光源的颜色,则会导致 。如果发生这种情况, 代码块会显示一条消息,提醒您在检视面板中设置光源。
tryNullReferenceExceptioncatch