C# 设置项的属性值会导致NullReferenceException

C# 设置项的属性值会导致NullReferenceException,c#,nullreferenceexception,C#,Nullreferenceexception,基本上我想做的是在客户列表中添加一个客户,在客户列表中有一个属性BillToContact。我想为客户创建一个实例BillToContact public class Customer { public string ID { get; set; } public string AccountName { get; set; } public Contact BillToContact { get; set; } } public class BillToCont

基本上我想做的是在客户列表中添加一个客户,在客户列表中有一个属性BillToContact。我想为客户创建一个实例BillToContact

public class Customer 
{
    public string  ID { get; set; }
    public string  AccountName { get; set; }
    public Contact BillToContact { get; set; }
}

public class BillToContact
{
    public string firstname { get; set; }
    public string LastName  { get; set; }
}

public class Contact
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
//下面是向客户添加BillToContact的尝试

public void test()
{
  List<Customer> Customer = new List<Customer>();

  Customer x = new Customer();
  x.ID   = "MyId";
  x.AccountName = "HelloAccount";
  x.BillToContact.FirstName = "Jim";
  x.BillToContact.LastName  = "Bob";

  Customer.Add(x);
}
公共无效测试()
{
列表客户=新列表();
客户x=新客户();
x、 ID=“MyId”;
x、 AccountName=“HelloAccount”;
x、 BillToContact.FirstName=“Jim”;
x、 BillToContact.LastName=“Bob”;
客户。添加(x);
}
此尝试的错误是一个错误

对象引用未设置为对象的实例


我还尝试在
Customer
内部创建一个
BillToContact
实例,但没有成功。为了避免任何混淆,问题是我试图在客户列表中创建一个实例,如果BillToContact

必须先实例化属性成员,然后才能设置其属性:

Customer x = new Customer();
x.ID   = "MyId";
x.AccountName = "HelloAccount";
x.BillToContact = new BillToContact();
x.BillToContact.FirstName = "Jim";
x.BillToContact.LastName  = "Bob";

仅实例化父类不会自动实例化任何组合类(除非您在构造函数中这样做)。

您必须先实例化属性成员,然后才能设置其属性:

Customer x = new Customer();
x.ID   = "MyId";
x.AccountName = "HelloAccount";
x.BillToContact = new BillToContact();
x.BillToContact.FirstName = "Jim";
x.BillToContact.LastName  = "Bob";

仅实例化父类不会自动实例化任何组合类(除非您在构造函数中这样做)。

您需要实例化BillToContact

因此,要么:

x.BillToContact = new BillToContact {FirstName = "Jim", LastName="Bob"};


两者都是等价的

您需要实例化BillToContact

因此,要么:

x.BillToContact = new BillToContact {FirstName = "Jim", LastName="Bob"};


两者都是等价的

其他两个答案都是正确的,因为对象需要实例化,但我发现了您的代码中的一个怪癖。无需创建名为
BillToContact
的单独类,因为它与
Contact
类共享完全相同的属性。如果您需要
BillToContact
除了
Contact
类中已有的属性之外还有更多属性,可以通过将
BillToContact
作为
Contact
的子类来执行继承

此外,您甚至可以从
Customer
的默认构造函数中进行构造函数调用,这样您就可以根据下面的示例,在知道对象不会为null的情况下立即赋值:

public class Customer 
{
    public string  ID { get; set; }
    public string  AccountName { get; set; }
    public Contact BillToContact { get; set; }

    //Contructor
    public Customer()
    {
        //Instantiate BillToContact 
        BillToContact = new Contact();
    }
}

Customer x = new Customer();
x.ID = "MyId";
x.AccountName = "HelloAccount";

//This would now work because BillToContact has been instantiated from within the constructor of the Customer class
x.BillToContact.FirstName = "Jim";
x.BillToContact.LastName  = "Bob";

Customer.Add(x);
或者,您也可以为
Contact
类创建一个构造函数,并让它接受名字和姓氏作为参数。通过这种方式,您可以创建一个新的
联系人
对象,并在一次点击中填充名字和姓氏,如下所示:

public class Contact
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Contact() {}

    public Contact(string firstName, string lastName)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
    }
}

Customer x = new Customer();
x.ID = "MyId";
x.AccountName = "HelloAccount";
x.BillToContact = new Contact("Jim", "Bob");
Customer.Add(x);

其他两个答案都是正确的,因为该对象需要实例化,但我发现您的代码有一个怪癖。无需创建名为
BillToContact
的单独类,因为它与
Contact
类共享完全相同的属性。如果您需要
BillToContact
除了
Contact
类中已有的属性之外还有更多属性,可以通过将
BillToContact
作为
Contact
的子类来执行继承

此外,您甚至可以从
Customer
的默认构造函数中进行构造函数调用,这样您就可以根据下面的示例,在知道对象不会为null的情况下立即赋值:

public class Customer 
{
    public string  ID { get; set; }
    public string  AccountName { get; set; }
    public Contact BillToContact { get; set; }

    //Contructor
    public Customer()
    {
        //Instantiate BillToContact 
        BillToContact = new Contact();
    }
}

Customer x = new Customer();
x.ID = "MyId";
x.AccountName = "HelloAccount";

//This would now work because BillToContact has been instantiated from within the constructor of the Customer class
x.BillToContact.FirstName = "Jim";
x.BillToContact.LastName  = "Bob";

Customer.Add(x);
或者,您也可以为
Contact
类创建一个构造函数,并让它接受名字和姓氏作为参数。通过这种方式,您可以创建一个新的
联系人
对象,并在一次点击中填充名字和姓氏,如下所示:

public class Contact
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Contact() {}

    public Contact(string firstName, string lastName)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
    }
}

Customer x = new Customer();
x.ID = "MyId";
x.AccountName = "HelloAccount";
x.BillToContact = new Contact("Jim", "Bob");
Customer.Add(x);

应该是……的复制品。。。但是有很好的答案…这不是同一个问题,我的上下文是不同的。我假设您已经仔细阅读了链接问题的答案,并将“间接”示例与您的代码进行了比较。如果你能链接到这个问题,并清楚地解释你调试的步骤,以及你的案例是如何完全不同的,那么你的问题会变得更好。。。但是有很好的答案…这不是同一个问题,我的上下文是不同的。我假设您已经仔细阅读了链接问题的答案,并将“间接”示例与您的代码进行了比较。如果你链接到这个问题并清楚地解释了你调试的步骤和你的案例是如何完全不同的,那么你的问题会明显好一些:考虑加入——建议改进代码是更合适的/值得赞赏的。更不用说这样了。不幸的是,也没有“扩展评论”类型的帖子,你的答案本质上是:侧记:考虑加入-建议改进代码是更合适的/欣赏的…更不用说这样了。不幸的是,这里也没有你的答案本质上是“扩展评论”类型的帖子。