设置项的属性值会导致NullReferenceException

时间:2015-01-26 22:20:12

标签: c# nullreferenceexception

基本上我要做的是在客户列表中添加客户,在客户列表中有一个属性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);
}

此尝试的错误是

  

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

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

3 个答案:

答案 0 :(得分:10)

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

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

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

答案 1 :(得分:8)

您需要实例化BillToContact

所以:

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

 x.BillToContact = new BillToContact();
 x.BillToContact.FirstName = "Jim";
 x.BillToContact.LastName = "Bob";

两者都是等价的

答案 2 :(得分:1)

其他两个答案都是正确的,因为对象需要实例化,但我发现了你的代码的怪癖。考虑到它与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类创建构造函数,并让它接受名字和姓氏作为参数。这样您就可以创建一个新的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);