空对象引用

时间:2010-09-16 14:58:53

标签: c# nunit null testing

使用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类型的通用列表。

那么,null在哪里?看起来很简单,它一定是我看不到的非常明显的东西。

6 个答案:

答案 0 :(得分: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;
}

执行此操作将实例化您的List,如果它在null时被调用。

答案 1 :(得分:2)

你应该先做:

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

答案 2 :(得分:1)

必须为SubReportsList,然后为null。

答案 3 :(得分:1)

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

答案 4 :(得分: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;
    }
 }
}

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

答案 5 :(得分:0)

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