C# 列表 属性

C# list property

我有一个已设置为 属性 的列表。我想从另一个 class 添加到此列表,但是当我 运行 我的代码告诉我我有空引用。但是,我可以很好地从列表中读取内容。只有当我添加到列表时才会显示错误。

我做错了什么?

属性 Class

public List<string> ownedShips;

void Start()
{
    ownedShips = new List<string> ();

}

public List<string> Ships
{
    get {return ownedShips;}
    set {ownedShips = value;}
}

正在从另一个 class 添加到列表中:

    public int shipCost; 
public bool purchasedShip;
public string shipName = "test";
TESTPlayerAccount player;


// Use this for initialization
void Start () 
{
    player = new TESTPlayerAccount ();
    Debug.Log (player.Currency);
}


public void BuyShip()
{
    if(player.Currency >= shipCost)
    {
        player.Ships.Add(shipName);

    }


}

您需要初始化支持 属性 的字段:

public List<string> ownedShips = new List<string>();

如果 'Player' class 的合约保证在实例化时调用 'Start',则不需要初始化支持字段。但是,即使是这样,这样做也是一种很好的防御做法。

我想你需要这样的东西

class TESTPlayerAccount 
{
    private List<string> ownedShips;

    public TESTPlayerAccount ()
    {
        ownedShips = new List<string>();    
    }

    public List<string> Ships
    {
        get {return ownedShips;}
    }
}

您似乎在使用名为 Start 的函数来代替 constructors。如果您必须在创建 class 实例时初始化某些东西,那么 constructor 是可行的方法,因为它将被自动调用。

public class TESTPlayerAccount 
{

    private List<string> ownedShips;

    public TESTPlayerAccount()
    {
        ownedShips = new List<string> ();

    }

    public List<string> Ships
    {
        get {return ownedShips;}
        set {ownedShips = value;}
    }

}

请注意,添加了一个构造函数 (public TESTPlayerAccount()) 来代替您的 Start() 函数。将 class 实例化为:

时,会在对象实例化时自动调用构造函数
TESTPlayerAccount player = new TESTPlayerAccount();

构造函数也可以有参数。除了已经存在的无参数构造函数 (public TESTPlayerAccount()) 之外,考虑以下可以添加到 TESTPlayerAccount 的构造函数:

public TESTPlayerAccount(string shipToAddAtStart)
{
    ownedShips = new List<string> ();

    this.Ships.Add("The best ship evor!");
}

对于这两个构造函数,您有不同的行为。

在无参数构造函数中 public TESTPlayerAccount() 您的列表已初始化,仅此而已。

在第二个构造函数中 public TESTPlayerAccount(string shipToAddAtStart) 您可以提供一个初始元素以添加到列表中。当然,您可能不需要第二个构造函数,只是将其扔在那里以表明您可以为 class 拥有多个构造函数,它采用不同的参数并执行不同的行为。

您需要初始化列表。如果你想在调用 new 时收集集合,你真的应该在构造函数中这样做。此外,C# 具有自动属性,这意味着您只需编写:

Public List<string> MyList {get; set;}

此外,理想情况下,您希望将 属性 作为接口公开。 .net 通用集合为您提供:

IEnumerable<T>
ICollection<T>
IList<T>

在您的 class 中,您可以将这些接口中的任何一个实例化为列表,但公开的类型更加灵活。

根据评论判断,我假设您使用的是 Unity。

如果为真,则 Start() 函数仅被从 MonoBehaviour class.

继承的 class 调用

对于不继承自 MonoBehaviour 的自定义 class,将 Start() 函数更改为默认构造函数,如下所示:

测试玩家账号:

public List<string> ownedShips;

public TESTPlayerAccount()
{
    ownedShips = new List<string> ();
}

public List<string> Ships
{
    get {return ownedShips;}
    set {ownedShips = value;}
}