List.Count 引发空引用异常
List.Count Raises Null Reference Exception
我正在 Unity 中创建一个 2D 宇宙飞船游戏。我有一个名为 "Player" 的 object,上面附有此脚本。在脚本中,我有这个 class 代表玩家的飞船:
public class Ship : MonoBehaviour
{
public List<Weapon> weaponsList;
void Start()
{
weaponsList = new List<Weapon>();
weaponsList.Add(new Weapon());
weaponsList.Add(new Weapon());
}
}
而这个 class(在同一个脚本中)代表武器:
public class Weapon
{
//properties here
}
现在,当我尝试使用此代码(来自不同脚本)引用 weaponsList 以获取 List.Count 时,它会抛出 NullReferenceException,提示 Object 引用未设置为 object:
Ship ship = GameObject.Find("Player").GetComponent<Ship>();
if (ship.weaponsList.Count >=2)
{
//do stuff
}
但是我尝试访问的任何其他 属性 船都工作正常。有人可以帮忙吗?如果您需要其他上下文或代码,请告诉我,我会进行必要的修改。
编辑: start 方法是 Unity 特有的,在脚本初始化时总是默认调用。
船舶不包含武器清单。
您可以使用
避免异常
Ship ship = GameObject.Find("Player").GetComponent<Ship>();
if (ship != null && ship.weaponsList != null && ship.weaponsList.Count >=2)
{
//do stuff
}
¿是否调用了 Start() 方法?
不要将武器列表的初始化放在 void Start()
中,而是放在对象的构造函数中。然后在创建飞船时,武器列表将始终初始化为零计数。构造函数应该始终将有问题的对象置于有效状态,以便可以使用它。有时,程序员会创建 Init() 或 Start() 方法来推迟昂贵的逻辑,直到方法真正需要它为止,但在这种情况下,我肯定会将该初始化放在构造函数中。
为避免此错误 将构造函数添加到您的 class
public class Ship : MonoBehaviour
{
public Ship()
{
weaponsList = new List<Weapon>();
}
public List<Weapon> weaponsList;
void Start()
{
weaponsList = new List<Weapon>();
weaponsList.Add(new Weapon());
weaponsList.Add(new Weapon());
}
}
调用Start()
时构造列表。如果在访问列表之前未调用 Start()
,则会出现您的错误。我的猜测是您试图在调用 Start()
之前访问该列表。
您应该考虑为 Ship
class 构建构造函数并将初始化代码放在那里:
public class Ship : MonoBehaviour
{
public List<Weapon> weaponsList;
public Ship()
{
weaponsList = new List<Weapon>();
weaponsList.Add(new Weapon());
weaponsList.Add(new Weapon());
}
}
一旦创建 class 的对象,就会调用此构造函数,您不必显式调用方法来构造对象的属性。
如果 Start()
没有被调用,你的 weaponsList
就是 null
... 或者它在某个时候变成 null
。将 public 变量更改为 public 属性 以拒绝外部调用者更改内部列表:
public class Ship : MonoBehaviour
{
public List<Weapon> weaponsList { get; private set; }
public Ship()
{
weaponsList = new List<Weapon>();
}
...
}
这可能会在应用程序的其他部分产生编译器错误。这些错误可能是 weaponsList
变成 null
.
的原因
在更好的编码实践方面,一些更多建议将 属性 更改为:
public IList<IWeapon> Weapons { get; private set; }
- 将
List
更改为接口。
- 将
Weapon
更改为 IWeapon
。
- 使用 Pascal 表示法(
Weapons
,而不是 weapons
)。
- 避免名称中的类型:
Weapons
,而不是 WeaponsList
(很明显这是一个列表)
我正在 Unity 中创建一个 2D 宇宙飞船游戏。我有一个名为 "Player" 的 object,上面附有此脚本。在脚本中,我有这个 class 代表玩家的飞船:
public class Ship : MonoBehaviour
{
public List<Weapon> weaponsList;
void Start()
{
weaponsList = new List<Weapon>();
weaponsList.Add(new Weapon());
weaponsList.Add(new Weapon());
}
}
而这个 class(在同一个脚本中)代表武器:
public class Weapon
{
//properties here
}
现在,当我尝试使用此代码(来自不同脚本)引用 weaponsList 以获取 List.Count 时,它会抛出 NullReferenceException,提示 Object 引用未设置为 object:
Ship ship = GameObject.Find("Player").GetComponent<Ship>();
if (ship.weaponsList.Count >=2)
{
//do stuff
}
但是我尝试访问的任何其他 属性 船都工作正常。有人可以帮忙吗?如果您需要其他上下文或代码,请告诉我,我会进行必要的修改。
编辑: start 方法是 Unity 特有的,在脚本初始化时总是默认调用。
船舶不包含武器清单。
您可以使用
避免异常Ship ship = GameObject.Find("Player").GetComponent<Ship>();
if (ship != null && ship.weaponsList != null && ship.weaponsList.Count >=2)
{
//do stuff
}
¿是否调用了 Start() 方法?
不要将武器列表的初始化放在 void Start()
中,而是放在对象的构造函数中。然后在创建飞船时,武器列表将始终初始化为零计数。构造函数应该始终将有问题的对象置于有效状态,以便可以使用它。有时,程序员会创建 Init() 或 Start() 方法来推迟昂贵的逻辑,直到方法真正需要它为止,但在这种情况下,我肯定会将该初始化放在构造函数中。
为避免此错误 将构造函数添加到您的 class
public class Ship : MonoBehaviour
{
public Ship()
{
weaponsList = new List<Weapon>();
}
public List<Weapon> weaponsList;
void Start()
{
weaponsList = new List<Weapon>();
weaponsList.Add(new Weapon());
weaponsList.Add(new Weapon());
}
}
调用Start()
时构造列表。如果在访问列表之前未调用 Start()
,则会出现您的错误。我的猜测是您试图在调用 Start()
之前访问该列表。
您应该考虑为 Ship
class 构建构造函数并将初始化代码放在那里:
public class Ship : MonoBehaviour
{
public List<Weapon> weaponsList;
public Ship()
{
weaponsList = new List<Weapon>();
weaponsList.Add(new Weapon());
weaponsList.Add(new Weapon());
}
}
一旦创建 class 的对象,就会调用此构造函数,您不必显式调用方法来构造对象的属性。
如果 Start()
没有被调用,你的 weaponsList
就是 null
... 或者它在某个时候变成 null
。将 public 变量更改为 public 属性 以拒绝外部调用者更改内部列表:
public class Ship : MonoBehaviour
{
public List<Weapon> weaponsList { get; private set; }
public Ship()
{
weaponsList = new List<Weapon>();
}
...
}
这可能会在应用程序的其他部分产生编译器错误。这些错误可能是 weaponsList
变成 null
.
在更好的编码实践方面,一些更多建议将 属性 更改为:
public IList<IWeapon> Weapons { get; private set; }
- 将
List
更改为接口。 - 将
Weapon
更改为IWeapon
。 - 使用 Pascal 表示法(
Weapons
,而不是weapons
)。 - 避免名称中的类型:
Weapons
,而不是WeaponsList
(很明显这是一个列表)