Почему я получаю исключение NullReferenceException?

#c# #nullreferenceexception

#c# #исключение nullreferenceexception

Вопрос:

У меня есть задание из школы, и я почти закончил, осталось только одно. Я получаю исключение NullReferenceException каждый раз, когда запускаю программу. Все работает так, как должно, за исключением listview, где генерируется исключение.

Это из основной формы:

 private void UpdateListView()
{
    lstReservations.Clear();

    string[] seats = new string[m_seatMngr.GetSeatInfoStrings((SeatManager.DisplayOption)cmboBoxListAlternitives.SelectedIndex, out seats)];

    if (seats != null amp;amp; seats.Length > 0)
    {
        string[] split = new string[4];

        for (int i = 0; i < seats.Length; i  )
        {
            split = seats[i].Split('|');

            ListViewItem newItem = new ListViewItem(split[0]);
            newItem.SubItems.Add(split[1]);
            newItem.SubItems.Add(split[2]);
            newItem.SubItems.Add(split[3]);
            //Lägger till newItem till lstReservations
            lstReservations.Items.Add(newItem);
        }
    }
}
  

Именно эта строка вызывает исключение:

 seats[i].Split('|');
  

Вот метод GetSeatInfoString из класса SeatManager:

 public int GetSeatInfoStrings(DisplayOption choice, out string[] strSeatInfoStrings)
{
    strSeatInfoStrings = null;
    int count = GetNumOfSeats(choice);

    if (count <= 0)
    {
        return 0;
    }

    strSeatInfoStrings = new string[count];

    int i = 0; //counter for return array
    //Is the element corresponding with the index empty
    for (int index = 0; index < m_totNumOfSeats; index  )
    {
        switch (choice)
        {
            case DisplayOption.AllSeats:
                strSeatInfoStrings[index] = GetSeatInfoAt(index);
                i  ;
                break;
            case DisplayOption.ReservedSeats:
                if (m_nameList[index] != null)
                {
                    strSeatInfoStrings[i] = GetSeatInfoAt(index);

                    i  ;
                }
                break;
            case DisplayOption.VacantSeats:
                if (m_nameList[index] == null)
                {
                    strSeatInfoStrings[i] = GetSeatInfoAt(index);

                    i  ;
                }
                break;
            default:
                break;
        }
    }

    return i;
}
  

Я знаю, что такое исключение NullReferenceException, но я не могу найти, почему я его получаю. Места массива должны быть заполнены, если это проблема, что не так в методе GetSeatInfoString?

Ответ №1:

Эта строка:

 string[] seats = new string[m_seatMngr.GetSeatInfoStrings((SeatManager.DisplayOption)
    cmboBoxListAlternitives.SelectedIndex, out seats)];
  

Порядок неясен, но здесь есть два назначения seats — первое через out , второе со всеми null s (новый массив строк). Попробуйте вместо этого:

 string[] seats;
m_seatMngr.GetSeatInfoStrings((SeatManager.DisplayOption)
    cmboBoxListAlternitives.SelectedIndex, out seats);
  

Которое назначается только через «out».

Комментарии:

1. Порядок здесь точен. Метод вызывается первым, всегда, что означает, что массив всегда будет заполнен null

2. @Lasse я имел в виду следующее: обычному читателю это непонятно (если вы не читали спецификацию, что делают лишь немногие из нас). В общем, в любое время, когда это так, реструктурировать его, чтобы оно было однозначным для читателя , проще и лучше, чем знать правила спецификации.

3. Спасибо за помощь. Сначала я сделал так, как вы предложили, но не запустил программу. Я подумал, почему метод возвращает целое число длины массива, когда мне не нужно его использовать. Но я должен выяснить, почему в listview ничего не добавляется, кроме пробелов. Текст не отображается, а заголовок исчез.

Ответ №2:

Вы должны научиться использовать отладчик, чтобы помочь отследить проблемы. Если вы пройдетесь по коду, вы увидите, что seats он содержит только null значения.

Проблема в этой строке:

 string[] seats = new string[m_seatMngr.GetSeatInfoStrings((SeatManager.DisplayOption)cmboBoxListAlternitives.SelectedIndex, out seats)];
  

Правая часть = должна быть оценена до того, как произойдет присвоение. Таким образом, даже если GetSeatInfoStrings присваивается seats , оно перезаписывается присваиванием.

В конце концов, все, что вы делаете, это:

string[] seats = new string[some_number];

И каждый элемент в этом массиве будет инициализирован null .

Однако в некотором смысле вы делаете слишком много в своем коде. Вы выделяете seats массив дважды. Все, что вам нужно сделать, это:

 string[] seats;
m_seatMngr.GetSeatInfoStrings((SeatManager.DisplayOption)cmboBoxListAlternitives.SelectedIndex, out seats);