NullReferenceException未被用户代码处理 - 对象引用未设置为对象的实例

7

我有以下C#类:

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; }
}

总的来说,Locales有Region、Buttons和Fields。Region有Center和East。Center和East有属性标题。Fields有标签,其中包含属性firstName、lastName和chooseLocale。
在一个名为GetLocale的方法中,我有以下代码:
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";

当我运行代码时,在以下行:englishLang.region.center.title = "Center Region"; 报出了 "NullReferenceException was unhandled by user code" 异常。
我在设置属性 title、save、firstName、lastName 和 chooseLocale 的方式上是否做错了什么?我尝试在 Locale englishLang = new Locale(); 之后,并在 englishLang.region.center.title = "Center Region"; 之前添加了以下代码块,但仍然收到错误消息。
Region region = new Region();
Center center = new Center();
East east = new East();
Buttons buttons = new Buttons();
Fields fields = new Fields();
Labels labels = new Labels();

我做错了什么?


1
如果这段代码的目的是支持不同的语言,我建议看一下 .Net 框架中的资源。 - treze
几乎所有的“NullReferenceException”异常情况都是相同的。请参考“.NET中的NullReferenceException是什么?”获取一些提示。 - John Saunders
4个回答

8
您的 Locales 对象从未实例化其属性,消费代码也不会实例化它们。作为引用类型,在该类中的属性具有默认值null。因此,当您执行以下操作时:
Locale englishLang = new Locale();

以下值为null:
englishLang.region
englishLang.buttons
englishLang.fields

因此,如果您尝试对这些字段进行取消引用,就像在这里所做的那样:NullReferenceException,您将收到一个异常。
englishLang.region.center.title = "Center Region";

那行代码试图通过引用其 center 属性来取消引用 englishLang.region。但是,regionnull,因为它尚未被实例化。
对于这些 DTO 类,最好的实例化位置可能在它们的构造函数中。类似这样:
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();
    }
}

这样一来,消费代码就不必手动执行此操作了,每次创建 Locales 实例时,字段都会自动实例化。当然,您还希望为其他对象重复相同的模式。


2
+1 - 我也认为拥有一个聚合其他类实例化它们的类比让类消费者承担这个任务更好。 - CAbbott

5

您需要实例化每个对象:

Locale englishLang = new Locale(); 
englishLang.region = new Region();
englishLang.region.center = new Center();
englishLang.region.center.title = "Center Region";

或者,您可以在父类的构造函数中实例化依赖项对象。并以此类推...

4

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

Locale englishLang = new Locale(); 
englishLang.region = new Region();
englishLang.region.center = new Center();
englishLang.region.center.title = "Center Region";

2

您正在使用自动属性,而默认情况下它们对于引用类型返回null。您需要在构造函数中初始化这些属性:

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; }
}

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接