Silverlight 添加到 List<T> 抛出未设置为对象实例的对象引用

Posted

技术标签:

【中文标题】Silverlight 添加到 List<T> 抛出未设置为对象实例的对象引用【英文标题】:Silverlight adding to List<T> throws Object reference not set to an instance of an object 【发布时间】:2011-04-15 05:06:48 【问题描述】:

我在 IE 8 上使用 Silverlight 4。我为 SharePoint 2010 创建了一个新的 Silverlight Web 部件,用于读取 2 种外部内容类型。一个代表来自 Code Plex 的 Chinook 数据库中的发票,另一个代表每张发票的行。我正在尝试使用 Telerik Rad GridView 控件在主从布局中显示代码。我已经以几种不同的方式尝试了这段代码。以下是一般描述: 我有 2 个对象 InvoiceHeader 和 InvoiceLine。

Invoice 标题包含 InvoiceLines 列表

public List<InvoiceLine> lines  get; set; 

我能够让它“工作”的唯一方法是使用 foreach 并循环浏览返回的发票,然后使用子 foreach(var invoice in returnedInvoices) 并将每一行添加到列表中,然后将列表添加到当前发票使用invoice.lines.Add(new InvoiceLine(line));

当然,问题是我无法使用lines.Clear() 清除行,或者在所有 InvoiceHeader 对象中清除了所有行。由于我无法清除清单,因此每张发票都将以下发票行添加到自己的行中。因此,我创建了一个 InvoiceHeaders 跟踪数组并尝试使用它来执行tracking[x].lines.Add(new InvoiceLine(line));,然后我在这篇文章的主题中收到了错误。尝试将 InvoiceLine 添加到 InvoiceHeader 对象的列表时,对象引用未设置为对象的实例。我不是真正的开发人员,所以我很感激你能给我的任何帮助。目前代码已经变得疯狂,所以对此我深表歉意。我在下面包含了successedCallback:

 void succeededCallback(object sender, ClientRequestSucceededEventArgs e)
    
        this.Dispatcher.BeginInvoke(() =>
            
                invoices.Clear();
                invoiceLines.Clear();
                int x = 0;
                int y = 0;
                foreach (var inv in returnedInvoices)
                
                    x++;
                

                InvoiceHeader[] tracker = new InvoiceHeader[x];

                foreach (var invoice in returnedInvoices)
                
                    tracker[y] = new InvoiceHeader(invoice);

                     //Get the lines that correspond to this invoice.
                    foreach (var line in returnedLines)
                    
                        if(line.FieldValues["InvoiceId"].ToString() == invoice.FieldValues["InvoiceId"].ToString())
                         
                            //tracker[y].lines.Add(new InvoiceLine(line));
                            /*
                             * If I comment out the line above
                             * I do not get the error, but I also
                             * don't get my detail level.
                             */
                        

                    

                    invoices.Add(tracker[y]);
                    if (y < x)  y++; 
                

                radGridView1234.ItemsSource = invoices;                        
            
            );
    

【问题讨论】:

【参考方案1】:

你什么时候初始化lines?通常,当用作自动属性时,集合属性只有一个带有私有 setter 的 getter。

public List<InvoiceLine> lines  get; private set; 

您必须初始化它,因为您当前在 null 上调用 .Add

lines = new List<InvoiceLIne>();

【讨论】:

Marc 和 anakata,谢谢你们!当然是这样!就我而言,这是一个非常愚蠢的错误。【参考方案2】:

我在您的代码示例中看不到对lines 的引用,我无法真正遵循,但此异常意味着您有一个空引用。像您的 lines 声明这样的自动属性具有该类型的默认初始值,对于 List 意味着 null,因此繁荣。

不建议直接通过属性公开列表,因为您将获得的行为很少符合您的预期,我建议您将其重构为封装私有和初始化字段的非自动属性,即:

// private field for your data
private List<InvoiceLine> _lines = new List<InvoiceLine>();

// public prop to expose it - but I'd be better still if I just exposed an Add method.
public List<InvoiceLine> Lines

  get  return this._lines; 

但是对于现在这个问题,最简单的做法是在尝试添加之前的某个时间点设置lines = new List&lt;InvoiceLine&gt;(); - 在构造函数中根据偏好设置。

【讨论】:

以上是关于Silverlight 添加到 List<T> 抛出未设置为对象实例的对象引用的主要内容,如果未能解决你的问题,请参考以下文章

在 Windows 窗体中将 list<T> 添加到列表框的类型错误

实体框架:绑定到 DataGridView 的 List<T> 添加回已删除对象以查看

MVC - 将动态添加的控件绑定到模型中的 List<T>

如何将多个 IEnumerable<IEnumerable<T>> 列表添加到 IEnumerable<List<int>>

Silverlight实用窍门系列:47.Silverlight中元素到元素的绑定,以及ObservableCollection和List的使用区别

在 WinForm 中将 List<T> 绑定到 DataGridView