Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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# Count引发空引用异常_C#_List_Unityscript - Fatal编程技术网

C# Count引发空引用异常

C# Count引发空引用异常,c#,list,unityscript,C#,List,Unityscript,我正在联合制作一个2D宇宙飞船游戏。我有一个名为“Player”的对象,它附带了这个脚本。在脚本中,我有一个代表玩家飞船的类: public class Ship : MonoBehaviour { public List<Weapon> weaponsList; void Start() { weaponsList = new List<Weapon>(); weaponsList.Add(new Weapon

我正在联合制作一个2D宇宙飞船游戏。我有一个名为“Player”的对象,它附带了这个脚本。在脚本中,我有一个代表玩家飞船的类:

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

    void Start()
    {
        weaponsList = new List<Weapon>();
        weaponsList.Add(new Weapon());
        weaponsList.Add(new Weapon());
    }
}
现在,当我尝试引用weaponsList以获取List.Count时,使用此代码(来自另一个脚本),它抛出一个NullReferenceException,表示对象引用未设置为对象的实例:

Ship ship = GameObject.Find("Player").GetComponent<Ship>();
if (ship.weaponsList.Count >=2)
{
    //do stuff
}
Ship Ship=GameObject.Find(“Player”).GetComponent();
如果(ship.weaponsList.Count>=2)
{
//做事
}
但我试图进入的船上的任何其他财产都可以正常工作。有人能帮忙吗?如果您需要其他上下文或代码,请让我知道,我将进行必要的编辑


编辑:start方法是Unity的专用方法,在脚本初始化时默认情况下始终调用。

飞船不包含武器列表

您可以使用

Ship ship = GameObject.Find("Player").GetComponent<Ship>();
if (ship != null && ship.weaponsList != null && ship.weaponsList.Count >=2)
{
    //do stuff
}
Ship Ship=GameObject.Find(“Player”).GetComponent();
如果(ship!=null&&ship.weaponsList!=null&&ship.weaponsList.Count>=2)
{
//做事
}

是否调用了Start()方法?

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

为了避免此错误将构造函数添加到类中

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());
    }
}
公共级船舶:单一行为
{
公共船舶()
{
武器列表=新列表();
}
公开武器清单;
void Start()
{
武器列表=新列表();
武器列表。添加(新武器());
武器列表。添加(新武器());
}
}

当调用
Start()
时,将构造该列表。如果在访问列表之前未调用
Start()
,则会出现错误。我猜您正在尝试在调用
Start()
之前访问列表

您应该考虑为<代码>船舶< /代码>类构造一个构造函数,并将初始化代码放在那里:

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

    public Ship()
    {
        weaponsList = new List<Weapon>();
        weaponsList.Add(new Weapon());
        weaponsList.Add(new Weapon());
    }
}
公共级船舶:单一行为
{
公开武器清单;
公共船舶()
{
武器列表=新列表();
武器列表。添加(新武器());
武器列表。添加(新武器());
}
}

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

如果未调用
Start()
,则您的
武器列表
null
。。。或者它在某个点变为
null
。将公共变量更改为公共属性以拒绝外部调用方更改内部列表:

public class Ship : MonoBehaviour 
{
    public List<Weapon> weaponsList { get; private set; }
    public Ship()
    {
        weaponsList = new List<Weapon>();
    }
    ...
}
  • 列表
    更改为界面
  • 武器更改为
    IWeapon
  • 使用帕斯卡符号(
    武器
    ,而不是
    武器
  • 避免在名称中键入:
    武器
    ,而不是
    武器列表
    (这是一个明显的列表)

这解决了问题。我对这个问题进行了编辑,指出Unity总是在脚本初始化之前调用Start()方法,因此我假设它的工作方式与构造函数相同。感谢您的建议。该解决方案会导致
武器列表
初始化两次。如果在调用
Start()
方法之前对
weaponsList
执行了任何操作,这将导致异常行为。最好从
Start()
方法中删除第二次初始化,甚至最好确保
武器列表
只能初始化一次和/或只能在
Ship
类内部初始化。
public class Ship : MonoBehaviour 
{
    public List<Weapon> weaponsList { get; private set; }
    public Ship()
    {
        weaponsList = new List<Weapon>();
    }
    ...
}
public IList<IWeapon> Weapons { get; private set; }