Мы запускаем систему и иногда получаем известное исключение NullReferenceException
с сообщением Object reference not set to an instance of an object
.
Тем не менее, в методе, где у нас есть почти 20 объектов, наличие журнала, в котором говорится, что объект нулевой, на самом деле вообще бесполезен. Это все равно что сказать вам, когда вы агент безопасности на семинаре, что человек из 100 участников - террорист. Это действительно бесполезно для вас. Вы должны получить больше информации, если вы хотите определить, какой человек является угрожающим человеком.
Аналогичным образом, если мы хотим удалить ошибку, нам нужно знать, какой объект является нулевым.
Теперь, что-то одержимо в моей голове в течение нескольких месяцев, а именно:
Почему .NET не дает нам имя или, по крайней мере, тип ссылки на объект, который является нулевым? , Разве он не может понять тип из отражения или любого другого источника?
Кроме того, каковы лучшие практики, чтобы понять, какой объект является нулевым? Должны ли мы всегда проверять обнуляемость объектов в этих контекстах вручную и регистрировать результат? Есть ли способ лучше?
Обновление:
исключение The system cannot find the file specified
имеет ту же природу. Вы не можете найти какой файл, пока не присоединитесь к процессу и не отладите. Я думаю, что эти типы исключений могут стать более разумными. Разве не было бы лучше, если бы .NET мог сказать нам c:\temp.txt doesn't exist.
вместо этого общего сообщения? Как разработчик, я голосую за.
источник
new
для создания экземпляров класса. Когда такой намек действительно помогает?Ответы:
В
NullReferenceException
основном говорит вам: вы делаете это неправильно. Ни больше ни меньше. Наоборот, это не полноценный инструмент отладки. В этом случае я бы сказал, что вы делаете это неправильно, потому чтоЯ большой поклонник проверки всего, прежде чем что-то пойдет не так, и предоставления хорошей информации разработчику. Вкратце: пишите чеки, используя
ArgumentNullException
лайки, и пишите имя самостоятельно. Вот пример:Вы также можете посмотреть на Code Contracts , у него есть свои причуды, но он работает довольно хорошо и экономит время при наборе текста.
источник
I only say that checking every object to get sure that it's not null, is not a good method
Серьезно. Это лучший метод. И не просто ноль, проверьте каждый аргумент на разумные значения. Чем раньше вы поймаете ошибки, тем легче найти причину. Вам не нужно возвращать несколько уровней в трассировке стека, чтобы найти вызывающий вызов.Это действительно должно показать именно то, что вы пытаетесь назвать. Это все равно что сказать: «Есть проблема. Тебе нужно ее исправить. Я знаю, что это такое. Я не собираюсь говорить тебе. Пойди разберись». По иронии судьбы, похоже на половину ответов об этом переполнении стека.
Так насколько полезным было бы, например, если бы вы получили это ...
...? Чтобы пройтись по коду, пройтись по нему и понять, что то, что вы пытаетесь назвать,
null
это хорошо, но почему бы просто не дать нам небольшую руку помощи?Я согласен, что обычно полезно пройтись по коду, чтобы найти ответ (потому что вы, вероятно, узнаете больше), но часто бы сэкономили много времени и разочарования, если бы
NullReferenceException
текст был больше похож на пример выше.Просто говорю.
источник
KeyNotFoundException
многих других неприятностей ...Ваш журнал должен включать в себя трассировку стека, которая обычно дает подсказку о том, какая строка в методе имеет проблему. Возможно, вам потребуется включить в сборку релиза символы PDB, чтобы вы знали, в какой строке находится ошибка.
Конечно, это не поможет вам в этом случае:
Принцип « не спрашивай» может помочь избежать такого кода.
Относительно того, почему информация не включена, я не уверен - я подозреваю, что, по крайней мере, в отладочной сборке, если они действительно захотят, они могли бы это выяснить. Может помочь создание аварийного дампа и открытие в WinDBG.
источник
Исключения были созданы как инструмент, чтобы сигнализировать исключительные нефатальные условия вверх по цепочке вызовов. То есть они не предназначены для отладки.
Если исключение с нулевым указателем было средством отладки, оно сразу же прерывало бы выполнение программы, позволяя подключаться отладчику, направляя его прямо на инкриминирующую строку. Это даст программисту всю контекстную информацию, которая доступна. (Это в значительной степени то, что делает Segfault из-за доступа с нулевым указателем в C, хотя и немного грубо.)
Однако исключение нулевого указателя разработано как допустимое условие времени выполнения, которое может быть сгенерировано и перехвачено в нормальном потоке программы. Следовательно, соображения производительности должны быть приняты во внимание. А любая настройка сообщения об исключении требует создания, объединения и уничтожения строковых объектов во время выполнения. Таким образом, статическое сообщение, несомненно, быстрее.
Я не говорю, что среда выполнения не может быть запрограммирована таким образом, чтобы получить имя инкриминирующей ссылки. Это может быть сделано. Это сделало бы исключения даже медленнее, чем они. Если кому-то это достаточно важно, такую функцию можно было бы сделать переключаемой, чтобы она не замедляла работу производственного кода, а позволяла упростить отладку; но почему-то никто, кажется, не заботился достаточно.
источник
Я думаю, что Cromulent ударил гвоздь по голове, но есть и очевидный момент: если у
NullReferenceException
вас есть неинициализированная переменная (и). Аргумент о том, что у вас есть около 20 объектов, передаваемых в метод, нельзя назвать смягчающим фактором: как создатель куска кода вы должны нести ответственность за его действия, что включает его соответствие остальной части кодовой базы, так как а также правильное и правильное использование переменных и т. д.это обременительно, утомительно и иногда скучно, но награды в конце стоят того: во многих случаях мне приходилось перелистывать файлы журналов весом в несколько гигабайт, и они почти всегда полезны. Однако, прежде чем вы перейдете к этому этапу, отладчик может помочь вам, и до этого этапа хорошее планирование избавит вас от многих трудностей (и я не имею в виду полностью спроектированный подход к решению кода): простые наброски и некоторые заметки могут и будут быть лучше чем ничего).
Что касается
Object reference not set to an instance of an object
кода, он не может угадать значения, которые нам могут понравиться: это наша работа как программистов, и это просто означает, что вы передали неинициализированную переменную в.источник
Научитесь пользоваться отладчиком. Это именно то, для чего она предназначена. Установите точку останова для рассматриваемого метода, и все готово.
Просто пройдитесь по своему коду и посмотрите, какие значения всех ваших переменных находятся в определенных точках.
Изменить: Честно говоря, я в шоке, что еще никто не упомянул об использовании отладчика.
источник
Если вы хотите пойти с ответом @ stijn и поставить нулевые проверки в своем коде, этот фрагмент кода должен помочь. Вот некоторая информация о фрагментах кода . Как только вы это настроите, просто введите
argnull
, дважды нажмите вкладку, а затем заполните пробел.источник
nameof
такой фрагментthrow new ArgumentNullException(nameof($argument$))
кода, который имеет такие преимущества, как отсутствие магических констант, проверка компилятором и лучшая работа с инструментами рефакторинга