简体   繁体   中英

C# a having a list inside a list of objects. Will not allow .add

I keep getting this error.

An unhandled exception of type 'System.NullReferenceException' occurred in CustomerExcelreader.exe

Additional information:

Object reference not set to an instance of an object.

Which I don't know why, since I have a global object, and I know the object works, since when I use non-list values of the object, everything works just fine.

This is the actual object in question.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CustomerExcelreader
{
public class customers
{
    public customers()
    {

    }
    /// <summary>
    /// These work just fine.
    /// </summary>
    public String Guest { get; set; }
    public String Contact { get; set; }
    public String ClubNumber { get; set; }//GuestNumber
    public String CasioNumber { get; set; }

    /// <summary>
    /// Lists of lists
    /// </summary>
    public List<String> Dates { get; set; }
    public List<String> Description { get; set; }
    public List<Double> moneyIN { get; set; }
    public List<Double> moneyOUT { get; set; }
    public List<Double> Balance { get; set; }
    public List<String> Remarks { get; set; }

}
}

and here is where it messes up with any of the List values, but normal variables are fine.

private void addButton_Click(object sender, EventArgs e)
{
    //customers add_customerHistory;
    if (listNames.SelectedIndex >= 0)// && listNames.SelectedIndex <= Pathlist.Capacity)//somehow SelectedIndex could be less then 0 by not picking something.
    {
        //add_customerHistory = CustomerHistoryList[listNames.SelectedIndex];
        textBox1.Text = CustomerHistoryList[listNames.SelectedIndex].ClubNumber;
        CustomerHistoryList[listNames.SelectedIndex].Dates.Add(DateBox.Text);
        CustomerHistoryList[listNames.SelectedIndex].Description.Add(DescriptionBox.Text);
        CustomerHistoryList[listNames.SelectedIndex].moneyIN.Add(Convert.ToDouble(InBox.Text));
        CustomerHistoryList[listNames.SelectedIndex].moneyOUT.Add(Convert.ToDouble(OutBox.Text));
        CustomerHistoryList[listNames.SelectedIndex].Balance.Add(Convert.ToDouble(BalanceBox.Text));
        CustomerHistoryList[listNames.SelectedIndex].Remarks.Add(RemarkBox.Text);
        //CustomerHistoryList[listNames.SelectedIndex].CasioNumber = "Its been changed";
        richTextBox1.Text = CustomerHistoryList[listNames.SelectedIndex].CasioNumber;

    }
    else
    {
        CustomerHistoryList[0].Dates.Add(DateBox.Text);
        CustomerHistoryList[0].Description.Add(DescriptionBox.Text);
        CustomerHistoryList[0].moneyIN.Add(Convert.ToDouble(InBox.Text));
        CustomerHistoryList[0].moneyOUT.Add(Convert.ToDouble(OutBox.Text));
        CustomerHistoryList[0].Balance.Add(Convert.ToDouble(BalanceBox.Text));
        CustomerHistoryList[0].Remarks.Add(RemarkBox.Text);
    }

}

It seems odd that it doesn't work here. I guess it has something to do with lists inside of objects? I heard those can act funky.

You need to initialise your list<String> properties in your class constuctor.

public class customers
{
    public customers()
    {
       Dates = new List<String>();
       Description = new List<String>();
       moneyIN  = new List<Double>();
       moneyOUT = new List<Double>();       
       Balance =  new List<Double>();
       Remarks = new List<String>();
    }


    // Other bits (not copied)



}

You have to create a new instance of a class ( List in your case), before accesing its members ( Add method in your case).

For example:

CustomerHistoryList[listNames.SelectedIndex].Dates = new List<string>();
CustomerHistoryList[listNames.SelectedIndex].Dates.Add(DateBox.Text);

As Chris Hammond pointed out, just because you use a property setter/getter does not mean that it will automatically create property values for you. This only happens with non nullable value types.

Either put the logic in your constructor or change them to private fields.

public class customers
{
    public customers()
    {
        this.Dates = new List<String>();
        this.Description = new List<String>();
        ...
    }

This makes it tricky for inheritance, so you can utilize private fields

public class customers
{
    private List<String> _dates = new List<String>();
    private List<String> _description = new List<String>();

    public List<String> Dates
    { 
        { return _dates; }
        { _dates = value; }
    }

    public List<String> Description
    { 
        { return _description; }
        { _description = value; }
    }

    ....

See this other post about exposing Generic Lists as Properties

Why is it considered bad to expose List<T>?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM