2010-09-16 125 views
2

使用NUnit测试用下面的代码块C#代码:空对象引用

foreach (XmlNode node in nodeList) 
{ 
    thisReport.Id = node.Attributes.GetNamedItem("id").Value; 
    thisReport.Name = node.Attributes.GetNamedItem("name").Value; 
    thisReport.Desc = node.Attributes.GetNamedItem("desc").Value; 
    if (node.SelectNodes("subreport").Count > 0) 
    { 
     thisReport.HasSubReport = true; 
     subReportNodeList = node.SelectNodes("subreport"); 
     foreach(XmlNode subNode in subReportNodeList) 
     { 
      mySubReport.ParentID = node.Attributes.GetNamedItem("id").Value; 
      mySubReport.Priority = subNode.Attributes.GetNamedItem("priority").Value; 
      mySubReport.SubReportId = subNode.Attributes.GetNamedItem("id").Value; 
      mySubReport.SubReportName = subNode.Attributes.GetNamedItem("name").Value; 
      string sTime = subNode.Attributes.GetNamedItem("time").Value; 
      mySubReport.Time = Convert.ToInt16(sTime); 
      thisReport.SubReportsList.Add(mySubReport); 
     } 
    } 
    else 
    { 
     thisReport.HasSubReport = false; 
    } 
    reports.Add(thisReport); 
} 

的代码失败就行了空对象引用:

  thisReport.SubreportsList.Add(mySubReport) 

但看当地人, thisReport存在并且具有在块顶部分配的值,并且存在mySubReport并且其值被添加到thisReport的行的上方。 mySubReport中的所有值都是有效的,SubReportsList中的thisReportSubReport类型的通用列表。

那么,零位在哪里呢?这看起来很简单,它一定是我看不到的真正明显的东西。

+2

如果'thisReport.SubReportsList.Add(mySubReport);'和'thisReport'和'mySubReport'中出现异常,那么唯一的选择是'thisReport.SubReportsList'为null。仔细检查你的财产实施。 – dtb 2010-09-16 15:02:07

+0

[在.NET中是什么是NullReferenceException?]的可能重复(http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-in-net) – 2012-05-28 12:58:15

回答

1

它必须是SubReportsList然后是null。

2

你可能应该先做到:

thisReport.SubReportsList = new List<SubReport>(); 
0

确保使用new关键字来初始化列表。否则,列表本身将为空。

5

在调用Add之前,您尚未实例化SubReportsList。加入mySubReport之前做到以下几点:

thisReport.SubReportsList = new List<SubReport>(); 
thisReport.SubReportsList.Add(mySubReport); 

你也可以改变你的SubReportsList属性,以使您的生活更轻松:

public class Report 
{ 
    public IList<SubReport> SubReportsList 
    { 
     get 
     { 
      if (_subReportsList == null) 
      { 
       _subReportsList = new List<SubReport>(); 
      } 
      return _subReportsList; 
     } 
    } 
    private IList<SubReport> _subReportsList; 
} 

这样做会实例化你的清单,如果这就是所谓的,而它的空。

1

thisReport.SubReportsList是你的空引用;你已经声明了它,但没有初始化它。您可以在构造函数thisReport的类型中初始化它(可能使用新实例),或者在开始向它添加事件之前对其进行初始化。

1

作为@GenericTypeTea和@Dan Dumitru已经提供了很好的答案我只是补充说,如果在调用属性时该值为null,则可以通过添加隐式构造来“自动”执行此操作。你可以,如果你不使用自动属性ALA做到这一点:

public class Report { 
// ... other code ... 
private List<SubReports> _subReports = null; 

public List<SubReport> SubReports { 
    get { 
     if (_subReports == null) { _subReports = new List<SubReports>(); } 
     return _subReports; 
    } 
} 
} 

有一些注意事项需要注意,像使它线程安全的(这是现成的,袖口),但基本实现将为你工作。我会小心使用这个设计,因为它可以通过检查属性来创建你不一定需要的对象。如果这是不可取的,那么坚持上面推荐的实现。

相关问题