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