Как этот код может генерировать исключение NullReferenceException? - PullRequest
4 голосов
/ 08 мая 2009

Я, должно быть, схожу с ума, потому что мои модульные тесты терпят неудачу, потому что следующий код выдает исключение нулевой ссылки:

int pid = 0;
if (parentCategory != null)
{
    Console.WriteLine(parentCategory.Id);
    pid = parentCategory.Id;
}

Строка, которая бросает это:

pid = parentCategory.Id;

console.writeline предназначен только для отладки в графическом интерфейсе NUnit, но при этом выдается действительный int.

Редактировать: Он однопоточный, поэтому его нельзя присвоить нулю из другого потока, и тот факт, что Console.WriteLine успешно выводит значение, показывает, что он не должен выбрасывать.

Редактировать: Соответствующие фрагменты класса Категория:

public class Category
{
    private readonly int id;

    public Category(Category parent, int id)
    {
        Parent = parent;
        parent.PerformIfNotNull(() => parent.subcategories.AddIfNew(this));
        Name = string.Empty;
        this.id = id;
    }
    public int Id
    {
        get { return id; }
    }
}

Ну, если кто-то хочет посмотреть полный код, он находится в Google Code на http://code.google.com/p/chefbook/source/checkout

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

Обновление: Загадка раскрыта. Похоже, NUnit показывает строку ошибки как последний успешно выполненный оператор ... Копирование / вставка теста в новое консольное приложение и запуск в VS показали, что это была строка после блока оператора if (не показан), который содержал нулевую ссылку. Спасибо всем за идеи. +1 всем, кто ответил.

Ответы [ 8 ]

7 голосов
/ 08 мая 2009

Исходя из всей информации, я до сих пор думаю, что либо "линия, которую бросают" неверна (что заставляет вас так думать), либо, возможно, ваши "источники" не синхронизированы с вашими собранными сборками.

Это выглядит невозможным, поэтому некоторые «само собой разумеющееся предположение» неверны, и, вероятно, это предположение, что «исходный код, который вы просматриваете, соответствует процессу, который вы отлаживаете».

3 голосов
/ 08 мая 2009

Когда все выглядит прямо на поверхности, то, скорее всего, вы бы что-то упустили. Вы уверены на 350%, что ваша DLL / PDB соответствует вашему исходному коду, что дает вам правильную строку?

  • Попробуйте вручную удалить свои сборки и запустить все, что вы используете. Не получается ли так, как надо?
  • Попробуйте очистить ваш раствор и перекомпилировать. Скопируйте сборки куда угодно и запустите снова. Это работает на этот раз? Нулевой реф в том же месте?
  • Отладка окружающих строк для значений, которые вы ожидаете. parentCategory и т. д. должны соответствовать тому, что вы думаете.
  • Изменить код, выдав исключение. Строки трассировки стека точно соответствуют строкам в вашем коде?

У меня были невероятно невероятные переживания, подобные этому, потому что одно из моих предположений было неверным. Типичным является несвежее собрание. Опросите все предположения.

2 голосов
/ 08 мая 2009

Что не имеет смысла, так это то, что OP заявляет, что console.writeline выводит допустимое значение int, и он вызывает то же свойство, что и строка, в которой он сообщает, что выдается ошибка.

Было бы полезно использовать трассировку стека или возможность посмотреть фактический модульный тест.

1 голос
/ 08 мая 2009

Я должен согласиться с Брайаном ... Возможно, вы используете устаревшие .pdbs, и код, который вы видите в режиме отладки, не соответствует коду, который фактически отлаживается.

Попробуйте очистить проект и перестроить его в режиме отладки.

1 голос
/ 08 мая 2009

Я не эксперт по C # и не уверен, что это что-то меняет, но вы отлаживаете в режиме отладки или в режиме выпуска? Если вы находитесь в режиме выпуска, строка, на которую указывает ваша IDE, и строка, на которой проблема на самом деле, может отличаться (я знаю, что это имеет место в C ++ при использовании Visual Studio)

1 голос
/ 08 мая 2009

Id мог бы иметь тип int со значением null (int?) Без значения, однако я чувствую, что свойство Id должно делать больше, чем просто возвращать int и что-то внутри, что является нулевым.

РЕДАКТИРОВАТЬ Ваше редактирование показывает, что это более чем необычно, не могли бы вы предоставить нам трассировку стека?

1 голос
/ 08 мая 2009

Да, можем ли мы увидеть код класса категории .. в частности, свойство Id? Предполагая, что свойство Id является целым (а не обнуляемым целым), метод get должен обращаться к объекту NULL.

0 голосов
/ 08 мая 2009

Похоже, что NUnit показывает строку ошибки как последний успешно выполненный оператор ... Копирование / вставка теста в новое консольное приложение и запуск в VS показали, что это была строка после блока оператора if (не показан), который содержал ноль ссылка Спасибо всем за идеи. +1 всем, кто ответил.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...