При добавлении Silverlight в список <T>выбрасывается ссылка на объект, не установленная на экземпляр объекта - PullRequest
0 голосов
/ 21 сентября 2010

Я использую Silverlight 4 в IE 8. Я создал новую веб-часть Silverlight для SharePoint 2010, которую я использую для чтения 2 внешних типов контента. Один представляет счета-фактуры в базе данных Chinook от Code Plex, а другой - строки каждого счета-фактуры. Я пытаюсь отобразить код в макете Master-Detail с помощью элемента управления Telerik Rad GridView. Я пробовал этот код несколькими разными способами. Вот общее описание: У меня есть 2 объекта InvoiceHeader и InvoiceLine.

Заголовок счета содержит список строк 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. Я на самом деле не разработчик, поэтому я был бы признателен за любую помощь, которую вы можете мне дать. В настоящее время код стал сумасшедшим, поэтому мои извинения за это. Я включил полученный ответ ниже:

 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;                        
            }
            );
    }

Ответы [ 2 ]

1 голос
/ 21 сентября 2010

Когда вы инициализируете lines? Как правило, свойства коллекции имеют только геттер с частным сеттером, если он используется в качестве автообъекта.

public List<InvoiceLine> lines { get; private set; }

Вы должны инициализировать его, так как вы в настоящее время звоните .Add на ноль.

lines = new List<InvoiceLIne>();
0 голосов
/ 21 сентября 2010

Я не могу увидеть ссылку на lines в вашем примере кода, которой я не мог следовать, но это исключение означает, что у вас нулевая ссылка.Автоматические свойства, такие как объявление строк, имеют начальное значение по умолчанию для типа, которое для списка означает ноль, следовательно, boom.

Не рекомендуется открывать списки напрямую через свойство, потому что поведение, которое вы получитередко соответствует тому, что вы хотели, и я бы посоветовал вам преобразовать его в не-autoprop инкапсулирующее приватное и инициализированное поле, то есть:

// 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<InvoiceLine>(); в какой-то момент, прежде чем пытаться добавить к нему - в конструкторе от предпочтения.

...