tags:

views:

67

answers:

3

I have the error "Object reference not set to an instance of an object." on the next method:

        private void alSave_Click(object sender, EventArgs e)
    {
        _alRecord.WriteXml(@".\alRecord.xml", XmlWriteMode.WriteSchema);
    }

and i don't know what can i do... here is the code:

        private string alFile = @".\alRecord.xml";

    public DataTable _alRecord;
    private DataTable alRecord
    {
        get
        {
            if (_alRecord == null)
            {
                _alRecord = new DataTable();
                if (File.Exists(alFile))
                { _alRecord.ReadXml(alFile); }
                else
                { InitDataTable2(_alRecord); }
            }
            return _alRecord;
        }
    }

    private void InitDataTable2(DataTable table)
    {
        table.TableName = "AlTable";
        table.Columns.Add("ID", typeof(int));
        table.Columns.Add("sun", typeof(bool));
        table.Columns.Add("mon", typeof(bool));
        table.Columns.Add("tue", typeof(bool));
        table.Columns.Add("wed", typeof(bool));
        table.Columns.Add("thu", typeof(bool));
        table.Columns.Add("fri", typeof(bool));
        table.Columns.Add("sat", typeof(bool));
        table.Columns.Add("doors", typeof(string));
        table.Columns.Add("from1", typeof(DateTime));
        table.Columns.Add("to1", typeof(DateTime));
        table.Columns.Add("from2", typeof(DateTime));
        table.Columns.Add("to1", typeof(DateTime));
        for (int i = 0; i < 99; i++)
        {
            var row = alRecord.NewRow();
            row["ID"] = i;
            row["sun"] = false;
            row["mon"] = false;
            row["tue"] = false;
            row["wed"] = false;
            row["thu"] = false;
            row["fri"] = false;
            row["sat"] = false;
            row["doors"] = "";
            row["from1"] = "00:01";
            row["to1"] = "23:59";
            row["from2"] = "00:01";
            row["to2"] = "23:59";
            alRecord.Rows.Add(row);
        }
    }
    private void alSave_Click(object sender, EventArgs e)
    {
        _alRecord.WriteXml(@".\alRecord.xml", XmlWriteMode.WriteSchema);
    }
+4  A: 
private void alSave_Click(object sender, EventArgs e) 
    { 
        _alRecord.WriteXml(@".\alRecord.xml", XmlWriteMode.WriteSchema); 
    } 

_alRecord is only loaded when you reference it by the property name, alRecord, hence that should be written as:

private void alSave_Click(object sender, EventArgs e) 
    { 
        alRecord.WriteXml(@".\alRecord.xml", XmlWriteMode.WriteSchema); 
    } 
James Curran
+1: I would really like it if there a 'property access only' modifier on field declarations.
Ani
Thx, it's working =)
Gilad Naaman
A: 

Edit:

public DataTable m_alRecord;// don't use it
private DataTable alRecord
{
    get
    {
        if (m_alRecord == null)
        {
            m_alRecord = new DataTable();
            if (File.Exists(alFile))
            { m_alRecord.ReadXml(alFile); }
            else
            { InitDataTable2(m_alRecord); }
        }
        return _alRecord;
    }
    set { m_alRecord = value; }
}
Andreas Rehm
If you remove the private variable, then the rest of yor code doesn't compile. (And if you reference the property within the getter, you'll fall into an infinite loop).
James Curran
You might need to read up on Auto-Implemented properties http://msdn.microsoft.com/en-us/library/bb384054.aspx To quote, "auto-implemented properties make property-declaration more concise **when no additional logic is required in the property accessors.** " Trying to compile your code I get "The name '_alRecord' does not exist in the current context"
Sam
I've edited my post - you're right. But you should use the Property all the time and not your member variable. This caused your code to fail...
Andreas Rehm
+1  A: 

You're using a technique called lazy initialization. _alRecord is not assigned until alRecord has been called.

Your alSave_Click method is using the wrong alRecord... it should be using the one without the underscore prefix. I.e.

private void alSave_Click(object sender, EventArgs e) 
{ 
    alRecord.WriteXml(@".\alRecord.xml", XmlWriteMode.WriteSchema); 
} 

As a side note, the scope of your alReord declarations seem to be the wrong way round (by convention that is).

public DataTable _alRecord; //Normally **private** members would have an underscore prefix    
private DataTable alRecord  //And public members would have no prefix.

Edit

By the way, once _alRecord has been assigned, then theoretically you could use it directly. However that defeats the purpose of the lazy initialization pattern.

E.g. The following would also work, but the point is you don't want to worry about whether _alRecord has been initialized, you just want to use it; and if it happens to be the first time you're using it, then it will be automatically initialized.

private void alSave_Click(object sender, EventArgs e) 
{ 
  alRecord;
  _alRecord.WriteXml(@".\alRecord.xml", XmlWriteMode.WriteSchema); 
} 
Craig Young
thank you for the private\public comment =)
Gilad Naaman