“Ссылка на объект не набор к экземпляру объекта”: почему.NET не может показать больше деталей?

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

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

Это - вероятно, одна из наиболее распространенных ошибок времени выполнения в.NET. Хотя Система. Исключение имеет отслеживание стека, нет никаких других полезных деталей.

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

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

15
задан Simon Chadwick 27 May 2010 в 02:38
поделиться

4 ответа

Это было рассмотрено здесь: Определение целевого объекта при возникновении исключения NullReferenceException

и здесь: Почему исключение с нулевой ссылкой не может назвать объект с нулевой ссылкой?

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

2
ответ дан 1 December 2019 в 05:02
поделиться

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

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

1
ответ дан 1 December 2019 в 05:02
поделиться

Разница между 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, может оказаться сложной задачей.

6
ответ дан 1 December 2019 в 05:02
поделиться

Я не нашел это исключение таким уж трудным!

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

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

0
ответ дан 1 December 2019 в 05:02
поделиться