System nullreferenceexception сообщение object reference not set to an instance of an object

Обновлено: 05.07.2024

У меня есть некоторый код, и когда он выполняется, он выдает NullReferenceException , говоря:

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

Чтобы использовать методы и член объекта, вы должны сначала создать этот объект. Если вы не создали его (переменная, которая должна содержать объект, не инициализирована), но вы пытаетесь использовать его методы или переменные, вы получите эту ошибку.

Иногда вы можете просто забыть выполнить инициализацию.

Отредактировано: new не может вернуть значение NULL, но возникает исключение при сбое. Давным-давно это было в некоторых языках, но не больше. Спасибо @Джон Сондерс за то, что указал на это.

Это означает, что ваш код использовал переменную ссылки на объект, для которой было установлено значение null (то есть он не ссылался на фактический экземпляр объекта).

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

например: допустим, у вас есть класс с именем myClass, и он содержит одно свойство prop1.

Теперь вы получаете доступ к этому prop1 в каком-то другом классе, как показано ниже:

вышеприведенная строка выдает ошибку, поскольку ссылка на класс myClass объявлена, но не создана, или экземпляр объекта не назначен для ссылки на этот класс.

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

Необработанное исключение:

System.NullReferenceException: ссылка на объект не установлена на экземпляр объекта. в Program.Main ()

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

здесь, если адрес равен нулю, вы получите NullReferenceException.

Таким образом, в качестве практики мы всегда должны использовать проверку null, прежде чем обращаться к свойствам в таких объектах (особенно в общем)

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

Затем следующий код вызовет исключение NullReferenceException при вызове context.SaveChanges ()

Ради полноты класса DataContext

и Связаться с объектом класса. Иногда классы сущностей являются частичными классами, так что вы можете расширять их и в других файлах.

Причина Я до сих пор не уверен в причине. Но всякий раз, когда какой-либо из классов сущностей расширяет System.Web.UI.Page, эта ошибка возникает.

Другой сценарий, когда вы бросаете нулевой объект в тип значения , Например, код ниже:

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

При работе на разных уровнях , например, в приложении MVC, контроллеру нужны сервисы для вызова бизнес-операций. В таких сценариях Контейнер внедрения зависимостей можно использовать для инициализации служб, чтобы избежать NullReferenceException . Таким образом, это означает, что вам не нужно беспокоиться о проверке на null и просто вызывать сервисы из контроллера, как если бы они всегда были доступны (и инициализированы) в виде одиночного или прототипа.

TL; DR: попробуйте использовать Html.Partial вместо Renderpage

Я получал Object reference not set to an instance of an object , когда пытался отобразить представление в представлении, отправив ему модель, например так:

Отладка показала, что модель была нулевой внутри MyOtherView. Пока я не изменил это на:

И это сработало.

Кроме того, причина, по которой у меня не было Html.Partial для начала, заключалась в том, что Visual Studio иногда выбрасывает выглядящие ошибочно волнистые линии в Html.Partial , если он находится внутри иначе построенного >, хотя на самом деле это не ошибка:

Хотя у меня такое ощущение, что Visual Studio неправильно читала амперсанды и скобки.

NullReferenceException или объектная ссылка, не установленная для экземпляра объекта, возникает, когда объект класса, который вы пытаетесь использовать, не создается. Например:

Предположим, что у вас есть класс с именем Student.

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

Как видно из приведенного выше кода, заявление Student s - объявляет только переменную типа Student. Обратите внимание, что на этом этапе класс Student не создается. Следовательно, когда оператор s.GetFullName () выполняется, он генерирует исключение NullReferenceException.

Это означает, что рассматриваемая переменная ни на что не указана. Я мог бы сгенерировать это так:

Чтобы избежать этой ошибки:

  1. Всегда инициализируйте ваши объекты, прежде чем пытаться что-либо с ними делать. Если вы не уверены, является ли объект нулевым, проверьте его с помощью object == null .

Инструмент JetBrains Resharper будет идентифицировать каждое место в вашем коде, в котором может быть ошибка нулевой ссылки, что позволяет вам поставить нулевую проверку. Эта ошибка - источник ошибок номер один, ИМХО.

Он используется для проверки на нулевое значение перед выполнением операции доступа к члену (?.) Или индекса (? [).

В результате имя будет нулевым, когда p равно нулю или когда p.Spouse равно нулю.

В противном случае имени переменной будет присвоено значение p.Spouse.FirstName.

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

Object reference not set to an instance of an object.

В экземпляре объекта не задана ссылка на объект.



2 ответа 2

Вкратце

Как и любое другое значение, null может передаваться от объекта к объекту, от метода к методу. Если нечто равно null в методе "А", вполне может быть, что метод "В" передал это значение в метод "А".

Остальная часть статьи описывает происходящее в деталях и перечисляет распространённые ошибки, которые могут привести к исключению NullReferenceException .

Более подробно

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

Это означает, что ссылка равна null , а вы не сможете вызвать методы через ссылку, равную null . В простейшем случае:

Этот код выбросит исключение NullReferenceException на второй строке, потому что вы не можете вызвать метод ToUpper() у ссылки на string , равной null .

Как определить источник ошибки? Кроме изучения, собственно, исключения, которое будет выброшено именно там, где оно произошло, вы можете воспользоваться общими рекомендациями по отладке в Visual Studio: поставьте точки останова в ключевых точках, изучите значения переменных, либо расположив курсор мыши над переменной, либо открыв панели для отладки: Watch, Locals, Autos.

Если вы хотите определить место, где значение ссылки устанавливается или не устанавливается, нажмите правой кнопкой на её имени и выберите "Find All References". Затем вы можете поставить точки останова на каждой найденной строке и запустить приложение в режиме отладки. Каждый раз, когда отладчик остановится на точке останова, вы можете удостовериться, что значение верное.

Следя за ходом выполнения программы, вы придёте к месту, где значение ссылки не должно быть null , и определите, почему не присвоено верное значение.

Несколько общих примеров, в которых возникает исключение.

Цепочка

Если ref1 , ref2 или ref3 равно null , вы получите NullReferenceException . Для решения проблемы и определения, что именно равно null , вы можете переписать выражение более простым способом:

Неявно

То же верно для вложенных инициализаторов:

Несмотря на использование ключевого слова new , создаётся только экземпляр класса Book , но экземпляр Person не создаётся, поэтому свойство Author остаётся null .

Массив

Элементы массива

Массив массивов

Collection/List/Dictionary

События

Неудачное именование переменных

Если бы в коде ниже у локальных переменных и полей были разные имена, вы бы обнаружили, что поле не было инициализировано:

Можно избежать проблемы, если использовать префикс для полей:

Если вы возвращаете пустую модель (или свойство модели) в контроллере, то вью бросит исключение при попытке доступа к ней:

Явно проверять на null , пропускать код

Если вы ожидаете, что ссылка в некоторых случаях будет равна null , вы можете явно проверить на это значение перед доступом к членам экземпляра:

Явно проверять на null , использовать значение по умолчанию

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

Явно проверять на null , выбрасывать своё исключение

Вы также можете бросать своё исключение, чтобы позже его поймать:

Использовать Debug.Assert для проверки на null для обнаружения ошибки до бросания исключения

Если во время разработки вы знаете, что метод может, но вообще-то не должен возвращать null , вы можете воспользоваться Debug.Assert для быстрого обнаружения ошибки:

Однако эта проверка не будет работать в релизной сборке, и вы снова получите NullReferenceException , если book == null .

Использовать GetValueOrDefault() для Nullable типов

Краткая запись для задания значения по умолчанию:

Это оператор безопасного доступа к членам, также известный как оператор Элвиса за специфическую форму. Если выражение слева от оператора равно null , то правая часть игнорируется, и результатом считается null . Например:

Разумеется, если переменная person может быть равна null , то надо проверять и её. Также можно использовать операторы ?. и ?? вместе, чтобы предоставить значение по умолчанию:

Если любой член в цепочке может быть null , то можно полностью обезопасить себя (хотя, конечно, архитектуру стоит поставить под сомнение):


@VladD Есть слишком много случаев, когда null — допустимое значение: ленивая инициализация, отсутствие значения "не задано" у типа и т. п. Не везде получается избавиться от null. Так что рекомендация сводится к "старайтесь не использовать null, если это возможно".

Это да, есть случаи, когда null валиден. Тогда, вероятно, первым вопросом должно быть: валиден ли null в этой точке? Если да, нужна проверка на null и адекватная реакция. Если нет, то код верен, а проблема где-то раньше (скорее всего в инициализации).

В дополнение к ответу @Discord @Squidward @Athari @Kyubey, давайте рассмотрим вопрос с другой стороны.

Если у вас в процессе выполнения программы случился NullReferenceException при доступе по какой-то ссылке, вы должны прежде всего задать себе важный вопрос:

а имеет ли право эта ссылка иметь значение null ?

Пример: если у вас есть такой класс:

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

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

А вот если вылетает обращение driver.Age , то здесь уже проблема прямо в точке обращения, вам необходимо сначала проверить, что driver != null , а потом уж обращаться.

Если же ссылка имеет право быть null -ом, то в этом случае нужно корректно обработать и этот случай.

В этом случае сам компилятор сможет проконтролировать, что вы забыли проинициализировать значение поля engine , и выдать вам предупреждение.

Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

Исключение, возникающее при попытке разыменования указателя NULL на объект.

Комментарии

NullReferenceExceptionИсключение возникает при попытке получить доступ к члену для типа, значение которого равно null . NullReferenceExceptionИсключение обычно отражает ошибку разработчика и возникает в следующих сценариях:

Вы забыли создать экземпляр ссылочного типа. В следующем примере names объявляется, но никогда не создается экземпляр:

Некоторые компиляторы выдают предупреждение при компиляции этого кода. Другие выдают ошибку, и компиляция завершается ошибкой. Чтобы устранить эту проблему, создайте экземпляр объекта, чтобы его значение больше не было null . В следующем примере это делается путем вызова конструктора класса типа.

Вы забыли размер массива перед его инициализацией. В следующем примере values объявляется как массив целых чисел, но число содержащихся в нем элементов никогда не указывается. Таким образом, попытка инициализировать свои значения вызвала NullReferenceException исключение.

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

Дополнительные сведения об объявлении и инициализации массивов см. в разделе массивы и массивы.

Вы получаете возвращаемое значение null из метода, а затем вызываете метод для возвращаемого типа. Это иногда приводит к ошибке в документации. в документации не заметка о том, что вызов метода может вернуть null . В других случаях код ошибочно предполагает, что метод всегда будет возвращать значение, отличное от null .

Код в следующем примере предполагает, что Array.Find метод всегда возвращает объект, Person поле которого FirstName соответствует строке поиска. Поскольку совпадений нет, среда выполнения создает NullReferenceException исключение.

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

Вы используете выражение (например, объединяете список методов или свойств) для получения значения и, несмотря на то, что проверяется, является ли значение null , среда выполнения по-прежнему вызывает NullReferenceException исключение. Это происходит из-за того, что одно из промежуточных значений в выражении возвращает null . В результате тест для null никогда не вычисляется.

В следующем примере определяется Pages объект, который кэширует сведения о веб-страницах, которые представлены Page объектами. Example.Main Метод проверяет, имеет ли текущая веб-страница заголовок, отличный от NULL, и отображает заголовок. Однако несмотря на эту проверку, метод создает NullReferenceException исключение.

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

В следующем примере определяется массив строк. for Оператор перечисляет элементы в массиве и вызывает метод каждой строки Trim перед отображением строки.

Это исключение возникает, если предполагается, что каждый элемент массива должен содержать значение, отличное от NULL, и значение элемента массива фактически null . Исключение можно устранить, проверив, находится ли элемент null перед выполнением какой-либо операции с этим элементом, как показано в следующем примере.

NullReferenceExceptionИсключение вызывается методом, который передается null . Некоторые методы проверяют передаваемые им аргументы. Если они выполняют и один из аргументов имеет значение null , метод создает System.ArgumentNullException исключение. В противном случае вызывается NullReferenceException исключение. Проиллюстрируем это на примере.

Чтобы устранить эту ошибку, убедитесь, что аргумент, передаваемый в метод, не имеет значение null , или обрабатывайте созданное исключение в try…catch…finally блоке. Дополнительные сведения см. в разделе Исключения.

Следующие инструкции промежуточного языка MSIL вызовут NullReferenceException : callvirt , cpblk , cpobj , initblk , ldelem. , ldelema , ldfld , ldflda , ldind. , ldlen , stelem. , stfld ,, и stind. throw unbox .

NullReferenceException использует COR_E_NULLREFERENCE HRESULT, имеющий значение 0x80004003.

Список начальных значений свойств для экземпляра NullReferenceException, см. в разделе NullReferenceException конструкторы.

Обработка NullReferenceException в коде выпуска

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

Однако существует много ситуаций, в которых процесс обработки ошибки может оказаться полезен:

Приложение может пропускать объекты, которые имеют значение null. Например, если приложение получает и обрабатывает записи в базе данных, можно игнорировать некоторое число неверных записей, которые вызывают возникновение объектов со значением null. Возможно, все, что потребуется, — записать неверные данные в файл журнала или интерфейс пользователя приложения.

Можно восстановить приложение до допустимого состояния. Например, вы могли выполнять задачу, состоящую из нескольких шагов, которая требует сохранения информации в хранилище данных, перед вызовом метода, который создает исключение NullReferenceException. Если неинициализированный объект повредит запись данных, можно будет удалить предыдущие данные перед закрытием приложения.

Конструкторы

Инициализирует новый экземпляр класса NullReferenceException с сериализованными данными.

Свойства

Получает или задает ссылку на файл справки, связанный с этим исключением.

Возвращает или задает HRESULT — кодированное числовое значение, присвоенное определенному исключению.

Возвращает экземпляр класса Exception, который вызвал текущее исключение.

Возвращает или задает имя приложения или объекта, вызывавшего ошибку.

Получает строковое представление непосредственных кадров в стеке вызова.

Возвращает метод, создавший текущее исключение.

Методы

Определяет, равен ли указанный объект текущему объекту.

При переопределении в производном классе возвращает исключение Exception, которое является первопричиной одного или нескольких последующих исключений.

Служит хэш-функцией по умолчанию.

При переопределении в производном классе задает объект SerializationInfo со сведениями об исключении.

Возвращает тип среды выполнения текущего экземпляра.

Создает неполную копию текущего объекта Object.

Создает и возвращает строковое представление текущего исключения.

События

Возникает, когда исключение сериализовано для создания объекта состояния исключения, содержащего сериализованные данные об исключении.

В теле метода решил просто проверить, будет ли работать заполнение объекта и т.д.
В чем может быть проблема? По идеи должна вернутся строка с двумя JSON массивами, где все кроме beachType будет null.

  • Вопрос задан более трёх лет назад
  • 13422 просмотра

freeExec

вот вы описали класс:


вот вы создали экземпляр класса в методе роута:
Tours tours = new Tours();

заметьте, конструктор отработал, но поле tourInfos так и осталось не инициализированным
затем вы пытаетесь обратиться к не инициализированному полю объекта

и получаете вполне закономерную ругань платформы на "обращение по несуществующей ссылке".
Вам нужно инициализировать в конструкторе Tours, поле tourInfos (new List()).
Но на этом ваша история не закончится, т.к. на строчках

система вам опять выбросит то же самое исключение, потому что у вас в коллекции tourInfos не существует ни одного экземпляра класса TourInfo, к которому вы пытаетесь обратится по индексу и изменить у него какое-то свойство. Сначала создайте эти объекты, затем добавьте их в лист, а уж потом доставайте их из листа по индексу и заполняйте необходимые свойства(ну или сначала создайте объекты, задайте им свойства, а потом добавляйте в лист).

public class Tours
public List tourInfos < get; set; >= new List();
>

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

Читайте также: