Подтвердить что ты не робот

"Ссылка на объект не установлена ​​в экземпляр объекта": почему .NET не может показать более подробную информацию?

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

Почему исключение не показывает также имя поля ссылки объекта или, по крайней мере, его тип?

Это, вероятно, одна из самых распространенных ошибок времени выполнения в .NET. Хотя в System.Exception есть трассировка стека, нет других полезных сведений.

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

Если экземпляры System.ArgumentNullException могут показывать имя параметра метода ( "Значение не может быть пустым. Имя параметра: значение" ), то, безусловно, экземпляры System.NullReferenceException может включать имя нулевого поля (или содержащую его коллекцию).

4b9b3361

Ответ 1

Разница между ArgumentNullException и NullReferenceException заключается в том, что ArgumentNullException всегда выбрасывается явно так:

if (parameter == null)
  throw new ArgumentNullException("parameter");

Если бы быстрый просмотр вывода ILDASM, локальные переменные действительно присутствуют внутри функции IL. Однако API по-прежнему не существует для программного поиска этих имен. Я понимаю, что это было бы довольно сложно, поскольку вам в основном нужно было бы построить дерево синтаксического анализа, представляющее функцию с областями, переменными, утверждениями и т.д.

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

Представьте себе следующее:

internalObject.OtherProperty = myObject.GetOtherObject().ThirdObject.SomeProperty == "value"
 ? myObject.OtherProperty
 : myObject.GetSomethingElse();

Там есть несколько точек отказа, и создание строки, представляющей фактически null, может быть сложным.

Ответ 2

Здесь описано: Обнаружение целевого объекта при вызове NullReferenceException

и здесь: Почему не может исключить исключение с помощью NULL-объекта, у которого есть нулевая ссылка?

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

Ответ 3

Несмотря на то, что имя и тип переменной могут существовать в коде MSIL, он не будет существовать в собственном коде, когда MSIL JITted.

Было бы невероятно неэффективно добавлять этот тип проверки в собственный код во время JITting - по существу, накладные расходы всякий раз, когда указатель разыменовывается.

Ответ 4

Я не нашел этого исключения, с которым трудно справиться!

Если я знаю номер строки. Я просто вставляю точку останова в эту строку, запускаю приложение в эту строку, и когда отладчик останавливается, я нахожу каждую переменную/объект в строке, и благодаря Visual Studio он показывает мне свои значения.

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