karnayanar Ответов: 3

c# NullReferenceException объявление целого числа


Привет Сообщество,

у меня проблема.
Почему он падает здесь с NullReferenceException?

не работать
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
   int a = 0; //<- throwing NullReference Exception. Why???
   a = Int32.Parse( textBoxWagenID.Text);
   m_EntityContext.Foo.Where( p => p.Bar == a).First();
}


Работающий
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
   DoSth();
}

private void DoSth()
{
   int a = 0; //<- not throwing NullReference Exception!!!!
   a = Int32.Parse( textBoxWagenID.Text);
   m_EntityContext.Foo.Where( p => p.Bar == a).First();
}


Разве это не одно и то же??

Florian Rappl

Вы уверены, что проблема именно в этом? Я очень в этом сомневаюсь.

Целое число никогда не даст вам нулевую ссылку, так как оно является структурой и поэтому выделяется в стеке (т. е. Даже неназначенная любая структура уже будет иметь значение. Единственный способ сделать это-использовать переменную типа int?. Но это не так.

Тем не менее, я видел коды, бросающие ошибки в других местах. Это может быть так и здесь.

Sergey Alexandrovich Kryukov

Думаю, вы совершенно правы. Я подозреваю, что причина в том, что сеанс отладки испорчен. Существуют относительно редкие ситуации, когда отладчик запутывается.
Пожалуйста, посмотрите мой ответ.
—СА

[no name]

просто попробовал это на моей машине, она работает нормально ... должно быть что-то еще

Sergey Alexandrovich Kryukov

Вы правы. Я подозреваю, что это ситуация, с которой я знаком: испорченный сеанс отладки — пожалуйста, смотрите мой ответ.
—СА

Wendelius

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

Sergey Alexandrovich Kryukov

Вы правы, этого не может быть.
Я подозреваю, что это ситуация, с которой я знаком: испорченный сеанс отладки — пожалуйста, смотрите мой ответ.
—СА

Jibesh

int a=0; никогда не бросайте исключение это может быть что-то другое, можете ли вы поставить try catch и скопировать стек исключений здесь.

private void textBox1_KeyDown(отправитель объекта, KeyEventArgs e)
{
пробовать {
int a = 0; / / < - исключение nullreference. Почему???
а = int32 значение.Синтаксический анализ( textBoxWagenID.Текст);
m_EntityContext.Фу.Где( Р =&ГТ; п.Бар == а).Первый();
}catch(исключение e)
{
строку сообщения = е.Метод toString();
}
}

скопируйте и вставьте то, что вы получаете в строке сообщения.

Вы можете использовать ссылку улучшить вопрос, чтобы изменить свой вопрос

Sergey Alexandrovich Kryukov

Вы правы, этого не может быть. Я подозреваю, что это ситуация, с которой я знаком: испорченный сеанс отладки — пожалуйста, смотрите мой ответ.
—СА

karnayanar

просто "ссылка на объект не установлена на экземпляр объекта".

karnayanar

Я попробовал следовать с отладчиком шаг за шагом:

private void textBox1_KeyDown(отправитель объекта, KeyEventArgs e)
{
int b; / / отладчик показывает -> b = 0; a = "" равно NULL
b = 1; / / отладчик показывает - > b = 1; a = "" равно NULL
int a; / / отладчик показывает -> b = 0; a = "" равно NULL
a = 1; / / < - выбрасывает исключение NullReference.
а = int32 значение.Синтаксический анализ( textBoxWagenID.Текст);
m_EntityContext.Фу.Где( Р =&ГТ; п.Бар == а).Первый();
}

Это интересно.

Таким образом, структура int является нулевой, даже если тип не является int?.

Может ли это иметь какое-то отношение к тому, что переменная используется в запросе?
Когда я не использую var a в запросе, он работает нормально.

Philippe Mori

Какая версия Visual Studio? Какой движок отладчика? И используете ли вы функцию редактирования и продолжения? Вы установили все обновления?

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

3 Ответов

Рейтинг:
27

Sergey Alexandrovich Kryukov

Если мои глаза не выдают меня, я уверен, что и Вы тоже. подарок ситуация правильная. Варианты кода функционально полностью эквивалентны, но это даже не главное. Суть в том, что строка кода, которую вы прокомментировали, в принципе не может вызвать исключение.

То, что происходит, может быть совершенно другим. В некоторых случаях, где отладчик показывает неправильные строки кода Я не знаю, как это воспроизвести, но это всегда происходит после долгого и похожего на спагетти сеанса отладки с некоторыми изменениями в коде. Может быть, результаты предыдущих сборников не очищены должным образом.

Итак, вот вам совет: закройте Visual Studio и очистите все проекты. А еще лучше удалить все существующие подкаталоги "obj"; обычно этого вполне достаточно. Снова запустите Visual Studio и выполните отладку очень точно, не изменяя свой код. Таким образом, вы увидите, что действительно происходит.

—СА


Wendelius

Очень верный.

Sergey Alexandrovich Kryukov

Спасибо, Мика.
—СА

fjdiewornncalwe

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

Sergey Alexandrovich Kryukov

Это почти то, что я сказал, но обычно перезагрузка не требуется, но удаление временных файлов (просто "obj") может скорее помочь. А он, в свою очередь, нуждается в перезапуске Visual Studio. Согласны?
—СА

Jibesh

Правильно. это странное поведение Visual Studio. если вы видите что-то странное с visual studio, не думайте дважды перезапускать!! это наиболее возможное решение.

fjdiewornncalwe

Абсолютно.

karnayanar

Я согласен.
Но я всегда пробовал это на разных компьютерах с одним и тем же результатом.

Jibesh

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

Sergey Alexandrovich Kryukov

Ну, это еще хуже...

karnayanar

ExceptionStack:

бей FooManager.Форма form1.textBox1_KeyDown(объекта Sender, KeyEventArgs E) в C:\FooManager\Form1.cs:Zeile 226.
система bei.Окна.Формы.Контроль.OnKeyDown(KeyEventArgs e)
система bei.Окна.Формы.Контроль.Вызова метода processkeyeventargs(сообщение&амп; м)
система bei.Окна.Формы.Контроль.ProcessKeyMessage(Message& m)
система bei.Окна.Формы.Контроль.WndProc (Message& m)
система bei.Окна.Формы.TextBoxBase.WndProc (Message& m)
система bei.Окна.Формы.текстовый.WndProc (Message& m)
система bei.Окна.Формы.Контроль.ControlNativeWindow.OnMessage (Message& m)
система bei.Окна.Формы.Контроль.ControlNativeWindow.WndProc (Message& m)
система bei.Окна.Формы.Родное окно.Обратного вызова(hwnd элемента указателя IntPtr, int32 и глутамат натрия, указателя IntPtr параметр wparam, указателя IntPtr lparam должен)

Sergey Alexandrovich Kryukov

Странный стек. Разве она не перевернута вверх ногами? Как вы думаете, где его вершина? То есть, что называется первым?
—СА

karnayanar

это то, что VS2010 выставил как стек.

Sergey Alexandrovich Kryukov

Ладно, может быть. Является ли это выходом исключения.Стек или...?
—СА

Andreas Gieriet

Мои 5!
Отладка a Клавиша вниз событие в любом случае не рекомендуется.
Овации
Энди

Sergey Alexandrovich Kryukov

Спасибо, Энди.
—СА

Рейтинг:
2

bangkokrat

К сожалению, ничто из вышеперечисленного не решило для меня ту же проблему. В конце концов я построил новый проект с минимальными зависимостями и все равно получил ошибку с той же целочисленной переменной, но после комментирования различных разделов кода смог отследить использование лямбда-выражения в list(of T).Find который использовал целочисленную переменную. Ага-оригинальная проблема выше-использование лямбда-выражения!

Чтобы проиллюстрировать это, проблемной переменной является "x". Целые числа до и после не вызывали проблем. Я мог бы пройти мимо этой переменной (x) после того, как прокомментировал везде, что она впоследствии была использована в подмене:

Public Sub ProcessNotifications()
        Try

            Dim assetList As New List(Of AssetInfo)

            Using reader As SqlDataReader = _dbUtils.GetNotificationSummary()

                If reader.HasRows Then

                    Dim notificationId As Integer = 0
                    Dim x As Integer = 0
                    Dim skywaveId As Integer = 0
                    Dim ai As AssetInfo = Nothing
                    Dim msg As MsgResponse = Nothing

Поскольку я раскомментировал различные разделы, виновник дальше был:
ai = assetList.Find(Function(p) p.AssetId = x)

Очевидный обходной путь состоит в том, чтобы перейти к циклу
for i = 0 to assetList.count - 1
Похоже, что карнаянар (11-янв-13 14:23 вечера выше) тоже думал об этом.

Было бы неплохо узнать, почему это происходит.... collections.generic является частью mscorlib, который является частью проекта .Net, и все мои ссылочные проекты используют то же самое .Чистая рамки (4.5.1).

У кого-нибудь еще есть идеи?

С уважением

Тим


[no name]

Вы должны задать свой собственный вопрос о своем коде, а не публиковать свой вопрос как решение чьего-то другого вопроса.

Рейтинг:
19

Andreas Gieriet

Мое подозрение:


  1. ваш обработчик событий KeyDown запускается, когда свойство Text Все еще равно null (т. е. событие регистрируется до установки свойства Text)
  2. int.Parse(...) вызывает исключение, если текст равен нулю.


Сделать следующее:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
   int a;
   if (textBoxWagenID != null && int.TryParse(textBoxWagenID.Text ?? string.Empty, out a))
   {
      m_EntityContext.Foo.Where( p => p.Bar == a).First();
   }
}


И еще: я бы не стал отлаживать это как событие KeyDown/KeyUp! Вы бы вызвали шторм событий во время отладки...

Овации
Энди

PS: в Visual Studio включите в диалоговом окне debuging --> Exceptions .Чистый исключение на этапе выполнения, чтобы остановить вечеринку. Вы будете promptet точный объект, который вызывает проблему. В этом случае наверняка либо textBoxWagenID, либо его текстовое свойство.


karnayanar

Спасибо, Энди.

Andreas Gieriet

Добро пожаловать.
Энди