List.Count引发空引用异常

时间:2016-06-08 20:15:35

标签: c# list unityscript

我正在Unity中创建2D太空飞船游戏。我有一个标题为“播放器”的对象,并附有此脚本。在脚本中,我有这个类代表玩家的船:

public class Ship : MonoBehaviour 
{
    public List<Weapon> weaponsList;

    void Start()
    {
        weaponsList = new List<Weapon>();
        weaponsList.Add(new Weapon());
        weaponsList.Add(new Weapon());
    }
}

这个类(在同一个脚本中)代表武器:

public class Weapon
{
    //properties here
}

现在,当我尝试使用此代码(来自不同的脚本)引用weaponList来获取List.Count时,它会抛出NullReferenceException,说Object引用未设置为对象的实例:

Ship ship = GameObject.Find("Player").GetComponent<Ship>();
if (ship.weaponsList.Count >=2)
{
    //do stuff
}

但我试图访问的任何其他船舶属性都可以。有人可以帮忙吗?如果您需要其他背景信息或代码,请告诉我,我会进行必要的修改。

编辑:启动方法对Unity来说是特殊的,并且在脚本初始化时始终默认调用。

5 个答案:

答案 0 :(得分:1)

船舶不包含武器清单。

您可以使用

来避免异常
Ship ship = GameObject.Find("Player").GetComponent<Ship>();
if (ship != null && ship.weaponsList != null && ship.weaponsList.Count >=2)
{
    //do stuff
}

¿方法Start()是否被调用?

答案 1 :(得分:1)

要避免此错误向您的班级添加构造函数

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());
    }
}

答案 2 :(得分:1)

如果weaponsList未被调用,则nullStart(),或者在某个时刻变为null。将公共变量更改为公共属性以拒绝外部调用者更改内部列表:

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(列表很明显)

答案 3 :(得分:0)

而不是将武器列表的初始化放在void Start()中,而是将它放在对象的构造函数中。然后,当船舶被创建时,武器列表将始终以零计数进行初始化。构造函数应始终将有问题的对象置于有效状态,以便可以使用它。有时,程序员创建Init()或Start()方法来推迟昂贵的逻辑,直到方法实际需要它,但在这种情况下,我肯定会将该初始化放在构造函数中。

答案 4 :(得分:0)

在调用Start()时构建列表。如果在访问列表之前未调用Start(),则会显示错误。我的猜测是你在调用Start()之前尝试访问列表。

您应该考虑为Ship类构建构造函数并将初始化代码放在那里:

public class Ship : MonoBehaviour 
{
    public List<Weapon> weaponsList;

    public Ship()
    {
        weaponsList = new List<Weapon>();
        weaponsList.Add(new Weapon());
        weaponsList.Add(new Weapon());
    }
}

只要创建了类的对象,就会调用此构造函数,并且您不必显式调用方法来构造对象的属性。