Модель MVC является нулевой во время публикации при циклическом просмотре списка [duplicate]

Попробуйте проверить файл www.conf nginx и убедитесь, что путь сокета правильный, и файл сокета присутствует в этом месте, пока эти службы запущены.

, т. е. /var/run/php/php7.0-fpm.sock или [!d1 ]

/dev/shm/php-fpm-www.sock

попытайтесь запустить php-fpm из init.d

/etc/init.d/php-7.0.0-fpm start

и проверьте файл php.ini также

, добавьте следующее в конец file

[apc]
apc.write_lock = 1
apc.slam_defense = 0
1878
задан 3 September 2017 в 19:06

28 ответов

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

In Visual Studio это обычно легко благодаря NullReferenceExceptions .

Во-первых, убедитесь, что правильная ошибка будет уловлена ​​- см. Как сделать разрешить нарушение «System.NullReferenceException» в VS2010? what

Тогда либо Как разрешить нарушение «Исключение System.NullReferenceException» в VS2010? или Прикрепить [отладчик VS] для выполнения процесса. Иногда может быть полезно использовать Debugger.Break, в котором будет предложено запустить отладчик.

Теперь, когда NullReferenceException выбрано (или необработанным), отладчик остановится (помните правило, установленное выше?). на линии, на которой произошло исключение. Иногда ошибка будет легко распознана.

Например, в следующей строке единственным кодом, который может вызвать исключение, является то, что myString имеет значение null. Это можно проверить, посмотрев на Attach [VS Debugger] на Running Process или выполнив выражения в окне Immediate.

var x = myString.Trim();

В более сложных случаях, таких как следуя ниже, вам нужно будет использовать один из методов выше (Watch или Immediate Windows) для проверки выражений, чтобы определить, было ли str1 пустым или если str2 имеет значение null.

var x = str1.Trim() + str2.Trim();

Once может быть исключение - это бросок, который был установлен, обычно это просто тривиально по отношению к причине назад, чтобы узнать, где введенное значение [неверно] -

. Найдите время, необходимое для понимания причина исключения. Проверьте нулевые выражения. Проверьте предыдущие выражения, которые могли бы привести к таким нулевым выражениям. Добавьте Immediate Window и, по мере необходимости, пройдите по программе. Использовать отладчик.

1 Если Break on Throws слишком агрессивен и отладчик останавливается на NPE в библиотеке .NET или сторонних разработчиков, Break on User-Unhandled может быть используется для ограничения исключений. Кроме того, VS2012 вводит Debugger.Break , который я рекомендую также включить.

Если вы отлаживаете с включенным Just My Code, поведение немного отличается. При включенном Just My Code отладчик игнорирует исключения с открытым кодом (CLR), которые выходят за пределы My Code и не проходят через My Code
41
ответ дан 15 August 2018 в 17:03

Если вы не инициализировали ссылочный тип и хотите установить или прочитать одно из его свойств, он выкинет исключение NullReferenceException.

Пример:

Person p = null;
p.Name = "Harry"; // NullReferenceException occurs here.

Вы можно просто избежать этого, проверив, является ли переменная не нулевой:

Person p = null;
if (p!=null)
{
    p.Name = "Harry"; // Not going to run to this point
}

Чтобы полностью понять, почему выбрано исключение NullReferenceException, важно знать разницу между типами значений и ссылочными типами.

Итак, если вы имеете дело с NullReferenceException , NullReferenceExceptions не может произойти. Хотя вам нужно сохранять предупреждения при работе со ссылочными типами!

Только ссылочные типы, как указывает название, могут содержать ссылки или буквально буквально ничто (или «нуль»). Если значения типов всегда содержат значение.

not

строка динамического объекта

Типы значений (вы можете просто игнорировать их) :

dynamic Интегральные типы object decimal string Пользовательские структуры struct
72
ответ дан 15 August 2018 в 17:03
  • 1
    -1: поскольку вопрос имеет значение «Что такое исключение NullReference», типы значений не имеют значения. – John Saunders 17 May 2013 в 03:00
  • 2
    @ Джон Сандерс: Я не согласен. Как разработчик программного обеспечения, действительно важно иметь возможность различать значения и ссылочные типы. иначе люди будут проверять, являются ли целые числа равными нулю. – Fabian Bigler 17 May 2013 в 03:28
  • 3
    Правда, просто не в контексте этого вопроса. – John Saunders 17 May 2013 в 03:44
  • 4
    Спасибо за подсказку. Я немного улучшил его и добавил пример сверху. Я все еще думаю, что упоминание Reference & amp; Типы значений полезны. – Fabian Bigler 17 May 2013 в 04:02
  • 5
    Я думаю, вы не добавили ничего, чего не было в других ответах, поскольку вопрос предполагает наличие ссылочного типа. – John Saunders 19 May 2013 в 04:24

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

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

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

8
ответ дан 15 August 2018 в 17:03

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

Случай с краем # 1: одновременный доступ к словарю

Родовые словари в .NET не являются потокобезопасными, и иногда они могут бросать NullReference или даже (чаще) a KeyNotFoundException при попытке получить доступ к ключу из двух параллельных потоков. Исключение в этом случае вводит в заблуждение.

Случай с краем # 2: небезопасный код

Если код NullReferenceException задан кодом unsafe, вы можете посмотреть на переменные указателя , и проверьте их на IntPtr.Zero или что-то в этом роде. Это одно и то же («исключение нулевого указателя»), но в небезопасном коде переменные часто переводятся в типы значений / массивы и т. Д., И вы ударяете головой о стену, задаваясь вопросом, как тип значения может исключение.

(Еще одна причина для неиспользования небезопасного кода, если вам это нужно, кстати)

7
ответ дан 15 August 2018 в 17:03
  • 1
    Пример словаря не является краевым случаем. Если объект не является потокобезопасным, то использование его из нескольких потоков приводит к случайным результатам. Пример вашего небезопасного кода отличается от null каким образом? – John Saunders 24 March 2017 в 06:03

Другим случаем, когда NullReferenceExceptions может случиться, является (неправильное) использование оператора as:

class Book {
    public string Name { get; set; }
}
class Car { }

Car mycar = new Car();
Book mybook = mycar as Book;   // Incompatible conversion --> mybook = null

Console.WriteLine(mybook.Name);   // NullReferenceException

Здесь Book и Car являются несовместимыми типами; a Car не может быть преобразован / передан в Book. Когда этот сбой завершается неудачно, as возвращает null. Используя mybook после этого, вы вызываете NullReferenceException.

В общем случае вы должны использовать cast или as, как показано ниже:

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

ComicBook cb = (ComicBook)specificBook;

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

ComicBook cb = specificBook as ComicBook;
if (cb != null) {
   // ...
}
65
ответ дан 15 August 2018 в 17:03
  • 1
    Это может произойти, когда распаковывает переменную. Я нахожу это часто случается в обработчиках событий после того, как я изменил тип элемента пользовательского интерфейса, но забыл обновить код. – Brendan 19 February 2014 в 06:24

Буквально самый простой способ исправить NullReferenceExeption имеет два пути. Если у вас есть GameObject, например, с прикрепленным скриптом и переменной с именем rb (rigidbody), эта переменная начнет пустую, когда вы начнете игру. Вот почему вы получаете NullReferenceExeption, потому что на компьютере нет данных, хранящихся в этой переменной.

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

Добавить RigidBody к вашему объект с AddComponent> Физика> Rigidbody Затем перейдите в свой скрипт и введите rb = GetComponent<Rigidbody>();. Эта строка кода работает лучше всего с вашими функциями Start() или Awake(). Вы можете добавить компонент программно и назначить переменную одновременно с одной строкой кода: rb = AddComponent<RigidBody>();

Дальнейшие заметки: если вы хотите, чтобы единство добавляло компонент к вашему объекту, и вы, возможно, забыли добавьте один, вы можете ввести [RequireComponent(typeof(RigidBody))] над объявлением класса (пробел ниже всех ваших операций). Наслаждайтесь и получайте удовольствие от игр!

0
ответ дан 15 August 2018 в 17:03

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

См. «Исключение NullReferenceException при проверке пользовательского атрибута авторизации» для несколько подробного примера.

38
ответ дан 15 August 2018 в 17:03

Ну, простыми словами:

Вы пытаетесь получить доступ к объекту, который не создан или в настоящее время не находится в памяти.

Итак, как это решить:

Отладить и отпустить отладчик ... Он сразу приведет вас к переменной, которая сломана ... Теперь ваша задача - просто исправить это. Используя новое ключевое слово в соответствующем месте. Если это вызвано некоторыми командами базы данных, потому что объект отсутствует, все, что вам нужно сделать, это выполнить нулевую проверку и обработать его:
if (i == null) {
    // Handle this
}
Самый сложный. Если GC собрал объект уже ... Это вообще происходит, если вы пытаетесь найти объект, используя строки ... То есть, найдя его по имени объекта, может случиться так, что GC уже может его очистить ... Это трудно найти и станет проблемой ... Лучший способ справиться с этим - делать нулевые проверки там, где это необходимо в процессе разработки. Это сэкономит вам много времени.

Находясь по имени, я имею в виду, что некоторые фреймворки позволяют использовать FIndObjects с помощью строк, а код может выглядеть так: FindObject («ObjectName»);

1
ответ дан 15 August 2018 в 17:03
  • 1
    Если у вас есть ссылка на объект, тогда GC никогда не очищает его – John Saunders 24 December 2015 в 11:51
  • 2
    если вы используете такие вещи, как FindObject («Имя объекта»), нет способа, которым GC будет знать перед вами, что вы собираетесь ссылаться на этот объект .. это то, что пыталось объяснить. Это происходит во время выполнения – Akash Chowdary 24 December 2015 в 12:11
  • 3
    Существуют некоторые рамки, которые обеспечивают эту функциональность на C #, например Unity. вопрос не имеет ничего общего с BCl. Поиск в Интернете до критики есть тонна функций, подобных им, и для получения дополнительной информации о себе я даже использую ее ежедневно. Теперь, пожалуйста, скажите мне, как ответ не делает ничего. – Akash Chowdary 24 December 2015 в 16:35
  • 4
    docs.unity3d.com/ScriptReference/… проверить ссылку и исправить urself mr.expert: p – Akash Chowdary 24 December 2015 в 16:54
  • 5
    Примеры, которые я видел в вашей ссылке, присваивают результаты GameObject.Find в поле участника. Это ссылка, и GC не будет собирать ее до тех пор, пока не будет собран содержащийся объект. – John Saunders 25 May 2016 в 21:00

В вопросе «что мне с этим делать» может быть много ответов.

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

Короче говоря, при разработке гарантирует, что будет некоторые ограничения в вашем классе, которые не будут нарушены при нормальном использовании (и, следовательно, класс не попадет в несогласованное состояние). Дизайн по контракту означает, что данные, данные как входные данные для функции / метода, должны соответствовать некоторым ограничениям, а «что я должен делать с этим» нарушают их, а постусловия означает, что a выход функции / метода должен снова следовать установленным ограничениям, не нарушая их. Условия контракта никогда не должны нарушаться во время выполнения программы без ошибок, поэтому дизайн по контракту проверяется на практике в режиме отладки, будучи инвариантами , чтобы максимизировать развитую производительность системы.

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

public X { get; set; }

public void InvokeX()
{
    X.DoSomething(); // if X value is null, you will get a NullReferenceException
}

Но если вы установите «свойство X никогда не должно иметь нулевого значения» в качестве предпосылки метода, вы можете предотвратить описанный выше сценарий:

//Using code contracts:
[ContractInvariantMethod]
protected void ObjectInvariant () 
{
    Contract.Invariant ( X != null );
    //...
}

По этой причине не существует для приложений .NET.

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

never Стоит отметить, что этот термин был придуман Бертран Мейер в связи с его дизайном языка программирования Эйфеля.

34
ответ дан 15 August 2018 в 17:03
  • 1
    Я думал добавить это, поскольку никто не упомянул об этом, и, поскольку он существует как подход, я намерен обогатить эту тему. – Nick L. 26 December 2014 в 05:03
  • 2
    Спасибо, что обогатили эту тему. Я дал свое мнение о вашем дополнении. Теперь другие могут сделать то же самое. – John Saunders 26 December 2014 в 05:05
  • 3
    Я думал, что это достойное дополнение к теме, учитывая, что это очень просматриваемая тема. Раньше я слышал о кодовых контрактах, и это было хорошим напоминанием о том, чтобы использовать их. – VoteCoffee 8 January 2015 в 06:03

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

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

@{
    MyEntity M = new MyEntity();
}
@RenderPage("_MyOtherView.cshtml", M); // error in _MyOtherView, the Model was Null

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

@{
    MyEntity M = new MyEntity();
}
@Html.Partial("_MyOtherView.cshtml", M);

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

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

@inherits System.Web.Mvc.WebViewPage
@{
    ViewBag.Title = "Entity Index";
    List<MyEntity> MyEntities = new List<MyEntity>();
    MyEntities.Add(new MyEntity());
    MyEntities.Add(new MyEntity());
    MyEntities.Add(new MyEntity());
}
<div>
    @{
        foreach(var M in MyEntities)
        {
            // Squiggly lines below. Hovering says: cannot convert method group 'partial' to non-delegate type Object, did you intend to envoke the Method?
            @Html.Partial("MyOtherView.cshtml");
        }
    }
</div>

Но я смог для запуска приложения без проблем с этой «ошибкой». Я смог избавиться от ошибки, изменив структуру цикла foreach, чтобы выглядеть так:

@foreach(var M in MyEntities){
    ...
}

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

28
ответ дан 15 August 2018 в 17:03
  • 1
    Вы хотели Html.Partial, а не @Html.Partial – John Saunders 24 July 2015 в 16:55
  • 2
    Кроме того, пожалуйста, покажите, какая строка выбрала исключение и почему. – John Saunders 24 July 2015 в 16:56
  • 3
    Ошибка произошла в MyOtherView.cshtml, которую я не включил сюда, потому что модель не была отправлена ​​должным образом (это было Null), поэтому я знал, что ошибка связана с тем, как я отправлял модель. – Travis Heeter 27 July 2015 в 14:44

Что вы можете сделать с этим?

Здесь есть много хороших ответов, объясняющих, что такое пустая ссылка и как ее отладить. [...] d1]

Что вы можете сделать с этим?

Например, , методы могут проверять разные аргументы, чтобы увидеть, являются ли они нулевыми и выбрасывают ArgumentNullException, исключение, явно созданное для этой точной цели.

Конструктор для ArgumentNullException даже принимает имя параметра и сообщение в качестве аргументов, чтобы вы могли точно сказать разработчику, в чем проблема.

public void DoSomething(MyObject obj) {
    if(obj == null) 
    {
        throw new ArgumentNullException("obj", "Need a reference to obj.");
    }
}

Использовать инструменты

Есть также несколько библиотек, которые могут помочь. Например, «Resharper» может предоставить вам предупреждения во время написания кода, особенно если вы используете их атрибут: NotNullAttribute

Там есть «Контракты Microsoft Code», в которых вы используете синтаксис вроде Contract.Requires(obj != null), который дает вам время выполнения и проверка компиляции: NotNullAttribute .

Также есть «PostSharp», который позволит вам просто использовать такие атрибуты:

public void DoSometing([NotNull] obj)

Сделав это и сделав PostSharp часть вашего процесса сборки obj будет проверена на нуль во время выполнения. См. «Ошибка проверки PostSharp»

Использование инструментов

Или вы всегда можете использовать свой собственный подход, используя простой старый код. Например, вот структура, которую вы можете использовать, чтобы поймать нулевые ссылки. Он моделируется по той же концепции, что и Nullable<T>:

[System.Diagnostics.DebuggerNonUserCode]
public struct NotNull<T> where T: class
{
    private T _value;

    public T Value
    {
        get
        {
            if (_value == null)
            {
                throw new Exception("null value not allowed");
            }

            return _value;
        }
        set
        {
            if (value == null)
            {
                throw new Exception("null value not allowed.");
            }

            _value = value;
        }
    }

    public static implicit operator T(NotNull<T> notNullValue)
    {
        return notNullValue.Value;
    }

    public static implicit operator NotNull<T>(T value)
    {
        return new NotNull<T> { Value = value };
    }
}

. Вы использовали бы очень похоже на то же, что использовали бы Nullable<T>, за исключением того, что цель заключалась в том, чтобы сделать ровно противоположное - не разрешать [F17]. Вот несколько примеров:

NotNull<Person> person = null; // throws exception
NotNull<Person> person = new Person(); // OK
NotNull<Person> person = GetPerson(); // throws exception if GetPerson() returns null

NotNull<T> неявно отбрасывается в и из T, поэтому вы можете использовать его практически в любом месте, где оно вам нужно. Например, вы можете передать объект Person методу, который принимает значение NotNull<Person>:

Person person = new Person { Name = "John" };
WriteName(person);

public static void WriteName(NotNull<Person> person)
{
    Console.WriteLine(person.Value.Name);
}

Как вы можете видеть выше, как с помощью nullable, вы получите доступ к базовому значению через Value имущество. Кроме того, вы можете использовать явный или неявный листинг, вы можете увидеть пример с возвращаемым значением ниже:

Person person = GetPerson();

public static NotNull<Person> GetPerson()
{
    return new Person { Name = "John" };
}

Или вы даже можете использовать его, когда метод просто возвращает T (в этом случае Person), выполнив бросок. Например, следующий код будет похож на код выше:

Person person = (NotNull<Person>)GetPerson();

public static Person GetPerson()
{
    return new Person { Name = "John" };
}

Объединить с Extension

Объединить NotNull<T> с методом расширения, и вы можете охватить еще больше ситуаций. Вот пример того, как может выглядеть метод расширения:

[System.Diagnostics.DebuggerNonUserCode]
public static class NotNullExtension
{
    public static T NotNull<T>(this T @this) where T: class
    {
        if (@this == null)
        {
            throw new Exception("null value not allowed");
        }

        return @this;
    }
}

И вот пример того, как он может быть использован:

var person = GetPerson().NotNull();

GitHub

Для вашей справки я сделал код выше, доступный в GitHub, вы можете найти его по адресу:

Ошибка проверки PostSharp

Объединить с Расширение

В C # 6.0 был введен «нуль-условный оператор», который немного помогает в этом. С помощью этой функции вы можете ссылаться на вложенные объекты, и если какой-либо из них null, все выражение возвращает null.

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

var address = country?.State?.County?.City;

Представьте, что country является объектом типа Country, который имеет свойство, называемое State и т. Д. Если country, State, County или City - null, тогда address will be null . Therefore you only have to check whether адрес is null`.

Это отличная функция, но это дает вам меньше информации. Это не делает очевидным, какой из 4 является нулевым.

Встроенный, как Nullable?

C # имеет красивое сокращение для Nullable<T>, вы можете сделать что-то NULL помещая знак вопроса после такого типа int?.

Было бы неплохо, если бы у C # было что-то вроде структуры NotNull<T> выше и имела аналогичную стенографию, может быть, восклицательный знак (!), чтобы вы могли написать что-то вроде: public void WriteName(Person! person).

20
ответ дан 15 August 2018 в 17:03
  • 1
    Никогда не бросайте исключение NullReferenceException – John Saunders 7 March 2016 в 00:35
  • 2
    @JohnSaunders осмелюсь спросить, почему? (Серьезно, хотя почему?) – Luis Perez 7 March 2016 в 19:29
  • 3
    Исключение NullReferenceException должно быть выбрано CLR. Это означает, что произошла ссылка на нуль. Это не означает, что ссылка на нуль будет происходить, за исключением того, что вы ловко проверили сначала. – John Saunders 7 March 2016 в 19:43
  • 4
    Я вижу вашу мысль о том, как это будет сбивать с толку. Я обновил его до обычного исключения для этого примера и настраиваемого исключения в GitHub. – Luis Perez 7 March 2016 в 22:41
  • 5
    Отличный ответ на такой основной вопрос. Это не так плохо, когда это ваш код, который терпит неудачу. Это ужасно, когда он приходит из глубины какой-то коммерческой сторонней библиотеки, на которую вы полагаетесь, и поддержка клиентов продолжает настаивать на том, что это должен быть ваш код, который вызывает проблему. И вы не совсем уверены, что это не так, и весь проект остановлен. Я действительно думаю, что это может сделать подходящую эпитафию для моего надгробного камня: «Ссылка на объект не установлена ​​в экземпляр объекта». – Darrel Lee 3 May 2016 в 07:01

Пример этого исключаемого исключения: когда вы пытаетесь что-то проверить, это null.

Например:

string testString = null; //Because it doesn't have a value (i.e. it's null; "Length" cannot do what it needs to do)

if (testString.Length == 0) // Throws a nullreferenceexception
{
    //Do something
} 

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

По сравнению с ArgumentNullException, которое обычно выбрасывается как защитная мера, если метод ожидает, что то, что происходит

Дополнительная информация находится в C # NullReferenceException и Null Parameter.

76
ответ дан 15 August 2018 в 17:03

У меня другая перспектива ответить на это.

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

public class MyController
{
    private ServiceA serviceA;
    private ServiceB serviceB;

    public MyController(ServiceA serviceA, ServiceB serviceB)
    {
        this.serviceA = serviceA;
        this.serviceB = serviceB;
    }

    public void MyMethod()
    {
        // We don't need to check null because the dependency injection container 
        // injects it, provided you took care of bootstrapping it.
        var someObject = serviceA.DoThis();
    }
}
36
ответ дан 15 August 2018 в 17:03
  • 1
    -1: это обрабатывает только один сценарий - неинициализированных зависимостей. Это сценарий меньшинство для исключения NullReferenceException. В большинстве случаев простое непонимание того, как работают объекты. Далее наиболее часто встречаются другие ситуации, когда разработчик предположил, что объект будет инициализирован автоматически. – John Saunders 7 March 2014 в 06:06
  • 2
    Все остальные уже были упомянуты выше. – Mukus 7 March 2014 в 06:23
  • 3
    Включение зависимостей обычно не используется, чтобы избежать исключения NullReferenceException. Я не считаю, что вы нашли здесь общий сценарий. В любом случае, если вы отредактируете свой ответ, чтобы он был больше в стиле stackoverflow.com/a/15232518/76337 , я удаляю нижний предел. – John Saunders 7 March 2014 в 06:30

Simon Mourier привел этот пример:

object o = null;
DateTime d = (DateTime)o;  // NullReferenceException

, где преобразование (cast) из unboxing из object (или из одного из классов System.ValueType или System.Enum или из типа интерфейса ) к типу значения (кроме Nullable<>) сам по себе дает NullReferenceException.

В другом направлении преобразование unboxing из a Nullable<>, который имеет HasValue, равный false ссылочному типу, может дать ссылку null, которая затем может привести к NullReferenceException. Классический пример:

DateTime? d = null;
var s = d.ToString();  // OK, no exception (no boxing), returns ""
var t = d.GetType();   // Bang! d is boxed, NullReferenceException

Иногда бокс происходит по-другому. Например, с помощью этого не общего метода расширения:

public static void MyExtension(this object x)
{
  x.ToString();
}

следующий код будет проблематичным:

DateTime? d = null;
d.MyExtension();  // Leads to boxing, NullReferenceException occurs inside the body of the called method, not here.

Эти случаи возникают из-за специальных правил, используемых во время выполнения при боксе Nullable<> экземпляров.

48
ответ дан 15 August 2018 в 17:03

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

object o = null;
DateTime d = (DateTime)o;

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

Одним из примеров этого является этот простой фрагмент привязки ASP.NET с элементом управления календарем:

<asp:Calendar runat="server" SelectedDate="<%#Bind("Something")%>" />

Здесь SelectedDate на самом деле является свойством - типа DateTime - типа Calendar Web Control, и привязка может отлично вернуть что-то null. Неявный генератор ASP.NET создаст кусок кода, который будет эквивалентен приведенному выше методу. И это поднимет NullReferenceException, что довольно сложно определить, потому что оно лежит в сгенерированном ASP.NET коде, который компилируется отлично ...

217
ответ дан 15 August 2018 в 17:03
  • 1
    Отличная добыча. Односторонний способ избежать: DateTime x = (DateTime) o as DateTime? ?? defaultValue; – Serge Shultz 29 June 2015 в 14:07

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

SqlConnection connection = null;
connection.Open();

Это вызовет ошибку, потому что, пока я объявил переменную «connection», она не указала ни на что. Когда я пытаюсь вызвать элемент «Open», для его разрешения нет ссылок, и он будет вызывать ошибку.

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

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

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

146
ответ дан 15 August 2018 в 17:03
  • 1
    Инструмент Resharper JetBrains определит каждое место в вашем коде, которое имеет возможность ошибки нулевой ссылки. Это неверно. У меня есть решение без этого обнаружения, но код иногда приводит к исключению. Я подозреваю, что это иногда невозможно обнаружить - по крайней мере, при использовании многопоточности, но я не могу комментировать дальше, потому что еще не идентифицировал местоположение моей ошибки. – j riv 21 January 2018 в 11:42
  • 2
    Но как решить его, когда NullReferenceException приходит в usign HttpContext.Current.Responce.Clear (). Это решение не решается ни одним из вышеперечисленных решений. потому что при создании объекта объекта HttpContext возникает ошибка «Разрешение перегрузки», потому что ни один доступный «Новый» не принимает это число аргументов. – Sunny Sandeep 2 February 2018 в 15:14

Имейте в виду, что независимо от сценария причина всегда одинакова в .NET:

Вы пытаетесь использовать ссылочную переменную, значение которой Nothing / null. Если для ссылочной переменной значение Nothing / null, это означает, что на самом деле оно не содержит ссылку на экземпляр любого объекта, который существует в куче. Вы либо никогда не присваивали какую-либо переменную, никогда не создавали экземпляр значения, присвоенного переменной, или вы вручную устанавливали переменную, равную Nothing / null, или вы вызывали функцию, которая устанавливала переменную в Nothing / null для вас.
90
ответ дан 15 August 2018 в 17:03

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

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

-1
ответ дан 15 August 2018 в 17:03

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

Например:

При использовании метода string пустой строки:
string str = string.Empty;
str.ToLower(); // throw null reference exception
Когда свойство нулевого объекта доступно:
Public Class Person {
    public string Name { get; set; }
}
Person objPerson;
objPerson.Name  /// throw Null refernce Exception 
32
ответ дан 15 August 2018 в 17:03
  • 1
    Это неверно. String.Empty.ToLower() не будет выбрасывать исключение с нулевой ссылкой. Он представляет собой действительную строку, хотя и пустую (т. Е. [F2]). Поскольку у этого объекта есть объект для вызова ToLower(), было бы бессмысленно бросать туда исключение с нулевой ссылкой. – Kjartan 24 July 2015 в 09:00

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

Пример:

string postalcode=Customer.Address.PostalCode; 
//if customer or address is null , this will through exeption

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

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

string postalcode=Customer?.Address?.PostalCode;
//if customer or address is null , this will return null, without through a exception
0
ответ дан 15 August 2018 в 17:03

Строка ошибки «Ссылка на объект, не установленная в экземпляр объекта.» указывает, что вы не назначили экземпляр объекта объектной ссылке, и все же вы получаете доступ к свойствам / методам этого объекта.

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

public Class myClass
{
   public int prop1 {get;set;}
}

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

public class Demo
{
     public void testMethod()
     {
        myClass ref = null;
        ref.prop1 = 1;  //This line throws error
     }
}

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

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

public class Demo
{
     public void testMethod()
     {
        myClass ref = null;
        ref = new myClass();
        ref.prop1 = 1;  
     }
}
7
ответ дан 15 August 2018 в 17:03

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

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

if (myvar != null)
{
    // Go ahead and use myvar
    myvar.property = ...
}
else
{
    // Whoops! myvar is null and cannot be used without first
    // assigning it to an instance reference
    // Attempting to use myvar here will result in NullReferenceException
}
135
ответ дан 15 August 2018 в 17:03

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

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

public class Student
{
    private string FirstName;
    private string LastName;
    public string GetFullName()
    {
        return FirstName + LastName;
    }
}

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

public class StudentInfo
{      
    public string GetStudentName()
    {
        Student s;
        string fullname = s.GetFullName();
        return fullname;
    }        
}

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

2
ответ дан 15 August 2018 в 17:03

Типы ссылок по умолчанию равны null, чтобы указать, что они не ссылаются на какой-либо объект. Следовательно, если вы попытаетесь получить доступ к объекту, на который ссылаетесь, и его нет, вы получите исключение NullReferenceException.

Для Ex:

SqlConnection connection = null;
connection.Open();

Когда вы запускаете это код: вы получите:

System.NullReferenceException: Object reference not set to an instance of an object.

Вы можете избежать этой ошибки следующим образом:

if (connection != null){
    connection.Open();
}

null

0
ответ дан 15 August 2018 в 17:03

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

-2
ответ дан 15 August 2018 в 17:03

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

Пример:

string value = null;
if (value.Length == 0) // <-- Causes exception
{
    Console.WriteLine(value); // <-- Never reached
}

Ошибка исключения:

Не обрабатывается Исключение: System.NullReferenceException: ссылка на объект не установлена ​​в экземпляр объекта. в Program.Main ()
59
ответ дан 15 August 2018 в 17:03
  • 1
    Как глубоко! Я никогда не считал константу «null» опорным значением. Так вот как C # абстрагирует «NullPointer». да? B / c, как я помню в C ++, NPE может быть вызвано разыменованием неинициализированного указателя (т. Е. Типа ref в c #), значением по умолчанию которого является адрес, который не назначен этому процессу (во многих случаях это было бы 0, особенно в более поздних версиях C ++, которые сделали автоинициализацию, принадлежащую OS-f, и умереть beeotch (или просто поймать sigkill, который ОС атакует ваш процесс)). – samsara 31 July 2013 в 23:55

Исправить исключение NullReferenceException можно с помощью Null-условных операторов в c # 6 и меньше писать код для обработки нулевых проверок.

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

Пример

  var name = p?.Spouse?.FirstName;

эквивалентен:

    if (p != null)
    {
        if (p.Spouse != null)
        {
            name = p.Spouse.FirstName;
        }
    }

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

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

Для получения дополнительной информации: Условные операторы

8
ответ дан 15 August 2018 в 17:03

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

Предположим, у вас есть веб-форма Contact.aspx, чей класс codebehind Свяжитесь с вами, и у вас есть имя объекта Contact.

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

Contact contact = new Contact { Name = "Abhinav"};
var context = new DataContext();
context.Contacts.Add(contact);
context.SaveChanges(); // NullReferenceException at this line

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

public class DataContext : DbContext 
{
    public DbSet<Contact> Contacts {get; set;}
}

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

public partial class Contact 
{
    public string Name {get; set;}
}

Ошибка возникает, когда и сущность, и класс codebehind находятся в одном пространстве имен. Чтобы исправить это, переименуйте класс сущности или класс codebehind для Contact.aspx.

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

Для обсуждения взгляните на NullReferenceException в DbContext.saveChanges ()

38
ответ дан 15 August 2018 в 17:03

Другие вопросы по тегам:

Похожие вопросы: