所以我开始学习面向对象编程,而且我在理解所有这些元素之间的关系方面遇到了一些麻烦。
我正在构建一个带有RPG风格战斗的简单文字游戏。
为此,我有几个课程,包括一个课程:
武器:
class Weapon
{
private string _name;
private int _mindamage;
private int _maxdamage;
public string Name { get { return _name; } set { _name = value; } }
public int MaxDamage { get { return _maxdamage; } set { _maxdamage = value; } }
public int MinDamage { get { return _mindamage; } set { _mindamage = value; } }
public Weapon(int mindamage, int maxdamage, string name)
{
this._name = name;
this._mindamage = mindamage;
this._maxdamage = maxdamage;
}
}
人物:
class Character
{
private string _name;
private int _life;
private Weapon _weapon;
public string Name { get { return _name; } set { _name = value; } }
public int Life { get { return _life; } set { _life = value; } }
public Weapon Weapon { get { return _weapon; } set { _weapon = value; } }
public Character(string name, Weapon weapon)
{
_name = name;
_weapon = weapon;
_life = 100;
}
我正在努力的那个: 它是一个表示列表中一组字符的类:
class Company
{
private int _size;
private List<Character> _members;
public int Size { get { return _size; } set { _size = value; } }
public List<Character> Members { get { return _members; } set { _members = value; } }
public Company(string[] names, Weapon[] weapons)
{
int length = names.Length;
List<Character> _members = new List<Character>();
for (int i = 0; i < length; i++)
{
_members.Add(new Character(names[i], weapons[i]));
Console.WriteLine("added {0} to character list", _members[i].Name);
}
Console.WriteLine("characters {0} and {1} exist after the for", _members[0].Name, _members[1].Name);
_size = length;
}
}
这段代码编译完全正常,但是当它执行时,如果我尝试访问列表中的字符名称,它会在我的Program.cs类中引发错误,例如:
static void Main(string[] args)
{
Weapon anduril = new Weapon(55, 80, "Anduril");
Weapon hache = new Weapon(25, 60, "hache");
Weapon lame = new Weapon(30, 50, "lame");
Weapon arc = new Weapon(30, 40, "arc");
string[] gentils = { "Aragorn", "Legolas", "Gimli" };
string[] méchants = { "Lurtz", "Berserk", "UrukA" };
Weapon[] armes = { anduril, arc, hache };
Weapon[] armes2 = { lame, lame, arc };
Company Communauté = new Company(gentils, armes);
Company Uruks = new Company(méchants, armes2);
Console.WriteLine(Communauté.Members[0].Name);
最后一行抛出了一个null对象错误。
正如您所看到的,我在Console.WriteLine
构造函数中调用了一些Company
来确保构造函数实际上将Character
添加到List
,并且它可以正常工作。那问题是什么?
是否与我为会员编写getter / setter的方式有关?
答案 0 :(得分:11)
List<Character> _members = new List<Character>();
声明了一个名为_members
的新本地,但您打算做的是初始化字段_members
。该字段永远不会被初始化,因此当您访问其成员时,空引用异常。
所以不要这样做。它应该是
this._members = new List<Character>();
甚至更好,在声明中初始化。
但真正的要点是:今天是学习使用调试器的好日子。您对程序的功能有一定的假设。这些假设是错误的。通过观察调试器中的程序并在每个步骤验证您的假设是否有效,您将很快发现错误。与在调试器中运行代码相比,盯着代码一小时,放弃并询问Stack Overflow是一种非常糟糕的调试技术。打印出程序的状态是一个很好的第一步,但实际上观察程序运行要好得多。
答案 1 :(得分:3)
不是填充_members类变量,而是通过声明一个新列表来启动一个名为_members的不同变量。
试试这个:
public Company(string[] names, Weapon[] weapons)
{
int length = names.Length;
_members = new List<Character>();
for (int i = 0; i < length; i++)
{
_members.Add(new Character(names[i], weapons[i]));
Console.WriteLine("added {0} to character list", _members[i].Name);
}
Console.WriteLine("characters {0} and {1} exist after the for", _members[0].Name, _members[1].Name);
_size = length;
}
答案 2 :(得分:2)
正如Eric Lippert所说 - 这是范围变量_members的问题。 但是你可以在你的函数中使用局部变量 - 就在结束复制到类成员之前:
this._members =_members;
最好将局部变量重命名为differente name:)
答案 3 :(得分:1)
在您的公司构造函数中,您将声明一个名为_members的新变量,该变量会影响类级别_members。
如果从构造函数中的_members之前删除List,它将使用正确的List并且应该有效。