关于C#:用户代码未处理NullReferenceException-对象引用未设置为对象的实例

NullReferenceException was unhandled by user code - Object reference not set to instance of an object

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

我有以下C类课程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class Locales
{
    public Region region { get; set; }
    public Buttons buttons { get; set; }
    public Fields fields { get; set; }
}

public class Region
{
    public Center center { get; set; }
    public East east { get; set; }
}

public class Center
{
    public string title { get; set; }
}

public class East
{
    public string title { get; set; }
}

public class Buttons
{
    public string save { get; set; }
}

public class Fields
{
    public Labels labels { get; set; }
}

public class Labels
{
    public string firstName { get; set; }
    public string lastName { get; set; }
    public string chooseLocale { get; set; }
}

总而言之,区域设置有区域、按钮和字段。该地区有中部和东部。中心和东部有产权。字段具有属性firstname、firstname和chooseLocale的标签。

在方法(称为GetLocale)中,我有以下代码:

1
2
3
4
5
6
7
Locale englishLang = new Locale();
englishLang.region.center.title ="Center Region";
englishLang.region.east.title ="East Region - Form";
englishLang.buttons.save ="Save";
englishLang.fields.labels.firstName ="First Name";
englishLang.fields.labels.lastName ="Last Name";
englishLang.fields.labels.chooseLocale ="Choose Your Locale";

当我运行代码时,一个"nullreferenceexception was unprocessed by user code"被抛出到行:englishLang.region.center.title ="Center Region";

我设置属性标题、保存、名字、姓氏和选择本地名称的方式有问题吗?我尝试在Locale englishLang = new Locale();之后和englishLang.region.center.title ="Center Region";之前添加以下代码块,但仍然收到错误消息。

1
2
3
4
5
6
Region region = new Region();
Center center = new Center();
East east = new East();
Buttons buttons = new Buttons();
Fields fields = new Fields();
Labels labels = new Labels();

我做错什么了?


您的Locales对象从不实例化其属性,消费代码也不实例化它们。作为引用类型,该类中的属性的默认值为null。所以当你这样做的时候:

1
Locale englishLang = new Locale();

以下值为null

1
2
3
englishLang.region
englishLang.buttons
englishLang.fields

因此,如果您尝试取消引用这些字段,您将收到一个NullReferenceException,就像您在这里所做的那样:

1
englishLang.region.center.title ="Center Region";

该行代码试图通过引用其center属性来取消引用englishLang.region。但是regionnull,因为它还没有被实例化。

在这些DTO类的情况下,最好在它们的构造函数中实例化这些类。像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Locales
{
    public Region region { get; set; }
    public Buttons buttons { get; set; }
    public Fields fields { get; set; }

    public Locales()
    {
        region = new Region();
        buttons = new Buttons();
        fields = new Fields();
    }
}

这样消耗代码的方式不必每次都手动执行此操作,只要创建EDOCX1的实例(0),构造函数就会自动实例化这些字段。当然,您将希望为其他对象重复相同的模式。


您必须实例化每个对象:

1
2
3
4
Locale englishLang = new Locale();
englishLang.region = new Region();
englishLang.region.center = new Center();
englishLang.region.center.title ="Center Region";

等等…

或者可以在父类的构造函数中实例化依赖对象。


在分配值之前,必须初始化属性/子属性:

1
2
3
4
Locale englishLang = new Locale();
englishLang.region = new Region();
englishLang.region.center = new Center();
englishLang.region.center.title ="Center Region";

您使用的是自动属性,默认情况下,它们返回null作为引用类型。您需要初始化属性,可能在构造函数中:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Locales
{
    public Locales()
    {
        this.region =  new Region();
        this.buttons = new Buttons();
        this.fields = new Fields();
    }

    public Region region { get; set; }
    public Buttons buttons { get; set; }
    public Fields fields { get; set; }
}

您还需要向其他类添加类似的代码。