【问题标题】:NullReferenceException was unhandled by user code - Object reference not set to instance of an object [duplicate]用户代码未处理 NullReferenceException - 对象引用未设置为对象的实例 [重复]
【发布时间】:2014-04-19 22:13:10
【问题描述】:

我有以下 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。地区有中部和东部。中心和东部拥有产权。字段具有标签,其具有属性 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";

当我运行代码时,会在以下行抛出“NullReferenceException 未被用户代码处理”:englishLang.region.center.title = "Center Region";

我在设置属性 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();

我做错了什么?

【问题讨论】:

  • 如果这段代码的目的是支持不同的语言,我建议看看 .Net 框架中的资源。
  • NullReferenceException 的几乎所有情况都是相同的。请参阅“What is a NullReferenceException in .NET?”获取一些提示。

标签: c# nullreferenceexception


【解决方案1】:

您正在使用自动属性,默认情况下它们返回 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; }
}

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

【讨论】:

    【解决方案2】:

    您的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 的实例,构造函数就会自动实例化这些字段。当然,您会希望对其他对象重复相同的模式。

    【讨论】:

    • +1 - 我也觉得有一个聚合其他类的类来实例化它们是一个好习惯,而不是让类消费者承担该任务的负担。
    【解决方案3】:

    你必须实例化每一个对象:

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

      【讨论】:

        猜你喜欢
        • 2011-02-07
        • 1970-01-01
        • 2012-05-27
        • 2020-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-19
        相关资源
        最近更新 更多