关于C#:”对象引用未设置为对象实例”尝试将对象添加到类内的列表时出错

“Object reference not set to an instance of an object” error when trying to add objects to a list inside a class

本问题已经有最佳答案,请猛点这里访问。

我定义了一些自定义类,其中包括类似这样的其他类的列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Unit
{
    public string Name { get; set; }
    public List<Group> Contains { get; set; }
}

public class Group
{
    public string Name { get; set; }
    public Type Type { get; set; }
    public int Number { get; set; }
}

public static Type basic_1 = new Type() { Name ="basic_1", Number = 1, Cost = 13 };

基本思想是你有一个单元,它包含一个组列表,每个组都有不同的类型。类型包含特定属性,而包含这些属性的类本质上是组织的。

然后我开始尝试像这样建立这些类:

1
2
3
Unit unit1 = new Unit() { Name ="Unit 1" };
Group group1 = new Group() { Name ="Group 1", Number = 10, Type = basic_1 };
unit1.Contains.Add(group1);

但在这里我收到错误(在Add方法中)"对象引用没有设置为对象的实例。"在调试器中,我看到UnitGroupType都是成功创建的,group1包含了它应该包含的Type值,但是unit1.Contains是n乌尔。

我做错什么了?仅供参考,我以前从来没有做过这样的事情,所以我甚至不知道是否有可能,但直到这一点,它似乎工作得很好。


您的List Contains从未初始化过,因此当您尝试访问它时,会得到一个空引用异常。本质上,所有空引用异常都是相同的,您试图使用一个空的对象。

在这种情况下,我们只需添加一个默认的构造函数来初始化列表。

1
2
3
4
5
6
7
8
9
10
11
public class Unit
{
    public string Name { get; set; }

    public List<Group> Contains { get; set; }

    public Unit()
    {
        Contains = new List<Group>();
    }
}

顺便说一下,Contains是一个糟糕的名字。Contains通常是一个函数调用,因为它是一个动词。通常最好用一个名词作集合,如Groups

1
2
3
4
5
6
7
8
9
10
11
public class Unit
{
    public string Name { get; set; }

    public List<Group> Groups { get; set; }

    public Unit()
    {
        Groups = new List<Group>();
    }
}


User类中的Contains列表永远不会被实例化。

您可以将您的User类改为:

1
2
3
4
5
6
7
8
9
10
11
public class Unit
{
    public string Name { get; set; }

    List<Group> list = new List<Group>();

    public List<Group> Contains
    {
        get { return list; }
    }
}

正如您所看到的,Contains属性现在只返回一个列表实例,该实例当然可以修改,但永远不会被重新影响。很可能,这就是你想要的。

虽然这超出了您的问题范围,但我建议您将Contains属性重命名为Groups


您已初始化单元,但Unit.Contains未初始化。在将对象添加到包含列表之前,必须对其进行初始化。

1
2
3
4
Unit unit1 = new Unit() { Name ="Unit 1" };
Group group1 = new Group() { Name ="Group 1", Number = 10, Type = basic_1 };
unit1.Contains = new List<Group>();
unit1.Contains.Add(group1);

在单元类构造函数中,可以在此处初始化列表中的代码

1
2
3
4
5
6
7
8
9
public class Unit
{
public string Name { get; set; }
public List<Group> Contains { get; set; }
public Unit()
{
Contains = new List<Group>();
}
}

我更喜欢第二个解决方案,因为它将确保每当单元初始化时,包含都将自动初始化。