Объекты класса / Создание экземпляра
Проблема заключается в том, что не создается объект CashFooister ; он объявляет только переменную с именем этого типа. Объявление переменной объекта и создание экземпляра — это две разные вещи.
средство
Оператор часто может быть использован для создания экземпляра при объявлении его:
Когда целесообразно создать экземпляр позже:
Примечание. Не используйте снова в процедуре, включая конструктор ( ):
Это создаст локальную переменную, которая существует только в этом контексте (sub). Переменной с уровнем модуля , который вы будете использовать везде остается .
Чтобы быть ясным, (или ) объявляет только переменную и ее . Объем переменной — существует ли она для всего модуля / класса или является локальным для процедуры — определяется , где она объявлена. определяет уровень доступа, а не область действия .
Для получения дополнительной информации см.
- Новый оператор
- Область применения Visual Basic
- Уровни доступа в Visual Basic
- Типы значений и ссылочные типы
5 ответов
Лучший ответ
Предположительно, это потому, что в VB.NET — это не совсем то же самое. как в C #.
В случае типов значений подразумевает значение по умолчанию этого типа. В случае значение по умолчанию — , поэтому приведение выполняется успешно.
РЕДАКТИРОВАТЬ : для дальнейшего пояснения причина, по которой второй пример выдает во время выполнения, заключается в том, что среда CLR пытается распаковать (ссылочный тип) в . Конечно, это не удается, потому что объект был инициализирован нулевой ссылкой (установив ее равной ):
Помните, что, как я объяснил выше, ключевое слово VB.NET по-прежнему работает так же, как в C #, когда дело касается ссылочных типов . Это объясняет, почему вы получаете , потому что объект, который вы пытаетесь преобразовать, является буквально пустой ссылкой. Он вообще не содержит значения и поэтому не может быть распакован в тип .
Вы не увидите такого же поведения, когда попытаетесь преобразовать ключевое слово в логическое значение, то есть:
Потому что ключевое слово (на этот раз в случае типов значений ) просто означает «значение по умолчанию для этого типа». В случае это , поэтому приведение логично и просто.
16
Cody Gray
26 Янв 2011 в 15:04
Чтобы получить ожидаемое поведение, вам понадобится этот код:
Символ означает .
1
Peter Mortensen
3 Авг 2013 в 12:51
Есть разница между использованием ключевого слова (буквального) и ссылочной переменной , значение которой равно .
-
Ссылочная переменная , значение которой равно , отличается. У вас нет особого поведения.
-
Очевидно, что не наследует и не реализует , если только вы не поместили упакованный в объектную переменную.
Таким образом, приведенный ниже код не работает во время выполнения за исключением.
2
Peter Mortensen
3 Авг 2013 в 12:51
Здесь вам нужно понять пару вещей.
первый — это то, что уже указали другие: может интерпретироваться компилятором VB как просто значение с учетом правильного контекста, например .
Это означает, что когда компилятор видит это:
Он видит литерал (), а также видит, что вы хотите использовать этот литерал как . Это делает его простым.
Но вот вторая вещь, которую вам нужно понять. на по сути является операцией распаковки (для типов значений). Итак, что должно произойти с точки зрения компилятора VB, так это: необходимо , чтобы в этом поле был , иначе операция завершится ошибкой. Поскольку на самом деле в поле ничего нет — а на этот раз мы действительно говорим ни о чем , как в — это вызывает исключение.
Если бы мне пришлось перевести этот код на C #, это выглядело бы так:
Надеюсь, это проясняет ситуацию?
4
Dan Tao
26 Янв 2011 в 15:05
Я обнаружил, что сравнение логической переменной со строкой «Истина», «Ложь» или «Нет ничего», похоже, гарантирует, что я получу правильные сравнения. Я использовал функцию для возврата html-строки div с изображением отмеченного или непроверенного переключателя, и у меня возникла проблема с тем, что ничего не возвращается как false. Использование строки variable = «True» или «False» и выполнение последней проверки с НИЧЕГО НЕ помогло решить эту проблему.
Кажется, что система выполняет преобразование в строку при неявном сравнении со строкой, тогда как использование метода .tostring просто создает ошибку, позволяя последнему сравнению фактически сравнивать со значением из ничего .
Надеюсь, это немного поможет. По крайней мере, позволил мне
1
Harry B.
3 Дек 2013 в 18:16
Определение
- Пространство имен:
- System
- Сборка:
- System.Runtime.dll
- Сборки:
- mscorlib.dll, System.Runtime.dll
- Сборка:
- mscorlib.dll
- Сборка:
- netstandard.dll
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Исключение, возникающее при попытке разыменования указателя NULL на объект.
В этой статье
- Наследование
-
Object
Exception
NullReferenceException
- Наследование
-
Object
Exception
SystemException
NullReferenceException
- Атрибуты
-
SerializableAttribute
ComVisibleAttribute
Визуальные базовые формы
Это довольно распространенный способ получить NRE. В C #, в зависимости от того, как он кодируется, IDE сообщит, что не существует в текущем контексте, или «не может ссылаться на нестатический член». Итак, в какой-то степени это ситуация только с VB. Это также сложно, потому что это может привести к отказу каскада.
Таким образом, массивы и коллекции не могут быть инициализированы. Этот код инициализации будет выполняться до того, как конструктор создаст или . В результате:
- Списки и коллекция будут просто пустыми
- Массив будет содержать пять элементов панели
- Назначение приведет к немедленному ЯРДУ , потому что ничто не не имеет свойства
После этого ссылки на элементы массива приведут к NRE. Если вы это сделаете , из-за нечетной ошибки, среда IDE может не сообщать об исключении, когда это произойдет. Исключение появится позже, когда ваш код попытается использовать массив. Это «молчаливое исключение» подробно описано в этом сообщении . Для наших целей ключ заключается в том, что когда что-то катастрофическое происходит при со
Похожие вопросы
- i’m in trouble with datareader
- Ошибка в маршрутизации в ASP.NET MVC
- Смешение битов в C #
- Sprache — Не удается распознать эту последовательность
- Linq возвращает список или один объект
- Использование лямбда-выражения для выбора элемента массива, в котор
- Как представить тип typeof (Int32 &) в DynamicMethod Emit
- Удалить кеш навигации в UWP
- AcmNotPossible вызов acmStreamOpen Error
Сравнение типов, допускающих значение null
Если в логических выражениях используются допускающие значения NULL переменные, результатом может быть , или . Ниже приведена таблица истинности для и . Поскольку у и теперь есть три возможных значения, можно вычислить девять комбинаций.
B1 | ячейк | B1 и B2 | B1 или B2 |
---|---|---|---|
Если значение логической переменной или выражения равно , то оно не равно ни . Рассмотрим следующий пример.
В этом примере принимает значение . В результате предложение выполняется в каждой инструкции, и выходные данные выглядят следующим образом:
Примечание
и , использующие сокращенную оценку, должны оценивать свои вторые операнды при первом вычислении до .
Объекты поставщика данных
Работа с базами данных представляет много возможностей для NullReference , потому что может быть много объектов ( , , , , , ….) в использовании сразу. Примечание
Неважно, какой поставщик данных вы используете — MySQL, SQL Server, OleDB и т. Д
— концепции одинаковы.
Пример 1
Как и прежде, объект myFoo был объявлен, но экземпляр никогда не создавался. Воля Если (MYFOO IsNot Nothing) AndAlso (myFoo.Bar IsNot Nothing) AndAlso (myFoo.Bar.Items не IsNot Nothing) Тогда …. существующий , не создать. В этом случае, поскольку это локальная переменная, IDE предупреждает вас, что это может произойти:
Когда объявляется как переменная уровня модуля / класса, как представляется , компилятор не может знать, был ли объект создан процедурой восходящего потока. Не игнорируйте предупреждения.
средство
Пример 2.
Опечатка проблема здесь: против . Не было создано никакого имени «Сотрудник», поэтому результаты пытаются получить к нему доступ. Другая потенциальная проблема заключается в том, что будет, что может быть и так, когда SQL включает предложение WHERE.
средство
Поскольку это использует одну таблицу, использование позволит избежать орфографических ошибок. Изучение также может помочь:
это функция, возвращающая число затронутых, которые также могут быть протестированы:
Пример 3.
Предоставление будет показано в предыдущем примере, но оно не анализирует имена из таблицы SQL или базы данных. В результате ссылки на несуществующую таблицу.
Устранение такой же, ссылки на таблицу с помощью индекса:
См. Также Класс DataTable .
Атрибуты в сигнатурах API
Анализ состояния NULL требует указаний от разработчиков для понимания семантики API. Некоторые API обеспечивают проверку значений NULL и должны изменять состояние NULL переменной с maybe-null на not-null. Другие API возвращают выражения, которые являются not-null или maybe-null в зависимости от состояния NULL входных аргументов. Для примера рассмотрим следующий код, в котором отображается сообщение:
Основываясь на проверке, любой разработчик будет считать этот код безопасным и не должен создавать предупреждения. Компилятор не знает, что обеспечивает проверку значения NULL. Атрибуты применяются для информирования компилятора о том, что переменная является not-null, только в том случае, если возвращает . В предыдущем примере сигнатура содержит , чтобы показать состояние NULL для :
Атрибуты предоставляют подробные сведения о состоянии NULL аргументов, возвращаемых значений и элементов экземпляра объекта, используемого для вызова элемента. Подробные сведения о каждом атрибуте можно найти в справочнике по языку об атрибутах ссылки, допускающих значения NULL. Все API среды выполнения .NET были аннотированы в .NET 5. Статический анализ можно улучшить, аннотировав API, чтобы предоставить семантическую информацию о состоянии NULL аргументов и возвращаемых значений.
Поиск причины
Поскольку проблема является ссылкой на объект , то есть ответ заключается в том, чтобы изучить их, чтобы выяснить, какой из них. Затем определите, почему он не инициализирован. Держите мышь над различными переменными, и Visual Studio (VS) покажет их значения — виновником будет .
Вы также должны удалить любые Try / Private arr как String () блоки из соответствующего кода, особенно те, где есть Private arr as String () = New String (10) {} ‘или Private arr () As String = New String ( 10) {} ‘Для локального массива (в процедуре) и использования «Option Infer»: Dim arr = New String (10) {} в блоке Option Infer. Это приведет к сбою вашего кода при попытке использовать объект, который есть . Это то, что вы хотите, потому что оно идентифицирует точное местоположение проблемы и позволяет идентифицировать вызывающий объект.
A в Catch, который отображает , мало поможет. Этот метод также приводит к очень плохим вопросам переполнения стека, потому что вы не можете описать фактическое исключение, объект или даже строку кода, где это происходит.
Вы также можете использовать ( Debug -> Windows -> Locals ) для изучения ваших объектов.
Как только вы знаете, что и где проблема, его обычно довольно легко исправить и быстрее, чем опубликовать параметр Strict.
7 ответов
Лучший ответ
Это один из самых больших источников путаницы с VB.Net, IMO.
в VB.Net является эквивалентом в C #: значение по умолчанию для данного типа.
- Для типов значений это, по сути, эквивалент «нуля»: для , для , для , …
- Для ссылочных типов это значение (ссылка, в общем-то, ничего не ссылающаяся).
Таким образом, оператор эквивалентен оператору , который, очевидно, не компилируется.
Решения: как говорили другие
- Либо используйте (т. Е. ). Это мое предпочтительное решение.
- Или используйте или эквивалентно
В контексте исходного кода вы можете использовать:
Более подробное объяснение можно найти на
144
jeroenh
20 Фев 2019 в 20:10
Способом обойти это было бы использование вместо этого типа данных Object:
Тогда вы можете не устанавливать дату так:
George Filippakos
14 Июл 2013 в 22:12
Вы можете проверить это, как показано ниже:
1
Sukhi
19 Май 2018 в 21:37
Вы также можете просто проверить следующее:
Он проверит, что переменная startDate типа данных DateTime имеет значение NULL или нет.
1
Mahavirsinh Padhiyar
30 Дек 2014 в 12:18
На любом языке программирования будьте осторожны при использовании значений NULL. В приведенном выше примере показана другая проблема. Если вы используете тип Nullable, это означает, что переменные, созданные из этого типа, могут содержать значение System.DBNull.Value; не то, чтобы он изменил интерпретацию установки значения по умолчанию с помощью «= Nothing» или что объект значения теперь может поддерживать нулевую ссылку. Просто предупреждение … удачного кодирования!
Вы можете создать отдельный класс, содержащий тип значения. Объект, созданный из такого класса, будет ссылочным типом, которому можно присвоить Nothing. Пример:
Конечный класс
‘в Main ():
Затем вы можете выбирать заменяемые элементы, чтобы заставить его делать то, что вам нужно. Работы много — но если она вам действительно нужна, вы справитесь.
1
sscheider
10 Апр 2012 в 17:26
DateTime — это тип значения , что означает, что он всегда имеет какое-то значение.
Это как целое число — оно может быть 0, 1 или меньше нуля, но никогда не может быть «ничем».
Если вам нужен DateTime, который может принимать значение Nothing, используйте DateTime, допускающий значение NULL.
4
Cheeso
3 Май 2011 в 12:50
DateTime — это тип значения, поэтому он не может быть нулевым. Вы можете проверить, чтобы он был равен , или вы можете использовать вместо него .
VB иногда «услужливо» заставляет вас думать, что он делает то, чего не делает. Когда он позволяет вам установить для Date значение Nothing, он действительно устанавливает для него какое-то другое значение, например MinValue.
См. этот вопрос для подробное обсуждение типов значений и ссылочных типов.
12
Community
23 Май 2017 в 12:10
Аннотации для переменных, допускающих значения NULL
Анализ состояния NULL надежен для большинства переменных. Компилятору требуются дополнительные сведения о переменных элементов. Компилятор не может делать предположения о порядке, в котором осуществляется доступ к открытым элементам. Доступ к любому открытому элементу можно получить в любом порядке. Любой из доступных конструкторов можно использовать для инициализации объекта. Если для поля элемента можно задать значение , в начале каждого метода компилятор должен предположить, что его состояние NULL — maybe-null.
Используйте аннотации, которые могут объявлять, является ли переменная ссылочным типом, допускающим значение NULL, или ссылочным типом, не допускающим значения NULL. Эти аннотации указывают на состояние NULL для переменных:
-
Ссылка не должна иметь значение NULL. Состоянием по умолчанию для ссылочной переменной, не допускающей значение NULL, является не равно NULL. Компилятор принудительно применяет правила, которые гарантируют, что можно разыменовать эти переменные без предварительной проверки того, что они не имеют значение NULL:
- Переменную необходимо инициализировать со значением, отличным от NULL.
- Переменной не может быть присвоено значение . Компилятор выдает предупреждение, когда код присваивает выражение maybe-null переменной, которая не должна иметь значение NULL.
-
Ссылка может иметь значение NULL. Состоянием по умолчанию для ссылочной переменной, допускающей значение NULL, является может быть NULL. Компилятор применяет правила, чтобы убедиться в правильности проверки для ссылки :
- Переменная может быть разыменована только в том случае, когда компилятор может гарантировать, что значение не равно .
- Эти переменные могут быть инициализированы со значением по умолчанию , и им можно присвоить значение в другом коде.
- Компилятор не выдает предупреждения, когда код присваивает выражение maybe-null переменной, которая может иметь значение NULL.
Любая ссылочная переменная, которая не должна быть равна , имеет состояние NULL not-null. Любая ссылочная переменная, которая может иметь значение , изначально имеет состояние NULL maybe-null.
Ссылочный тип, допускающий значение NULL использует тот же синтаксис, что и тип значения, допускающего значение NULL: к типу переменной добавляется . Например, следующее объявление переменной представляет строковую переменную, допускающую значение NULL, :
Любая переменная, где не добавляется к имени типа, является ссылочным типом, не допускающим значение NULL. Сюда входят все переменные ссылочных типов в существующем коде, если вы включили эту функцию. Однако любые неявные типизированные локальные переменные (объявленные с помощью ) являются ссылочными типами, допускающими значение NULL. Как было показано в предыдущих разделах, статический анализ определяет состояние NULL локальных переменных, чтобы узнать, являются ли они maybe-null.
Иногда необходимо переопределить предупреждение, если известно, что переменная не имеет значение NULL, но компилятор определяет ее состояние NULL как maybe-null. Используйте оператор, допускающий значение NULL перед именем переменной, чтобы принудительно задать для состояния NULL not-null. Например, если вы знаете, что переменная не имеет значение , а компилятор выдает предупреждение, напишите следующий код, чтобы переопределить анализ компилятора:
Ссылочные типы, допускающие значение NULL, и типы значений, допускающие значение NULL, предоставляют аналогичную семантическую концепцию: переменная может представлять значение или объект, либо эта переменная может быть . Однако ссылочные типы, допускающие значение NULL, и типы значений, допускающие значение NULL, реализуются по-разному: типы значений, допускающие значение NULL, реализуются с помощью System.Nullable<T>, а ссылочные типы, допускающие значение NULL, реализуются атрибутами, которые считывает компилятор. Например, и представлены одним и тем же типом: System.String. Однако и представлены и System.Int32 соответственно.
8 ответов
Лучший ответ
Если вы посмотрите на MSIL во время его выполнения, вы увидите, что он не компилируется до того же самого кода. Когда вы используете IsNothing (), он фактически вызывает этот метод, а не просто вычисляет выражение.
Причина, по которой я склоняюсь к использованию «Is Nothing», заключается в том, что когда я отрицаю, это становится «IsNot Nothing», а не «Not IsNothing (объект)», что, по моему мнению, выглядит более читабельным.
126
lomaxx
8 Авг 2008 в 16:28
Вы должны категорически избегать использования
Вот 4 причины из статьи IsNothing. () VS — это ничто
-
Самое главное, что имеет все, что передается ему как объект, даже типы значений! Поскольку типы значений не могут быть , это напрасная проверка. Возьмем следующий пример:
Это будет компилироваться и работать нормально, тогда как это:
Компилировать не будет, вместо этого компилятор выдаст ошибку:
-
на самом деле является частью . Это нежелательно, поскольку у вас есть ненужная зависимость от библиотеки VisualBasic.
-
Это медленно — на самом деле на 33,76% медленнее (более 1000000000 итераций)!
-
Возможно, личные предпочтения, но читается как Условие Йоды. Когда вы смотрите на переменную, вы проверяете ее состояние и рассматриваете ее как предмет вашего исследования.
т.е. выполняет ли это x? — НЕ . Является ли свойством it ?
Поэтому я думаю, что читается лучше, чем
35
KyleMit
30 Июн 2014 в 20:07
Я согласен с «Нет ничего». Как было сказано выше, легко отрицать «IsNot Nothing».
Мне это легче читать …
Чем это…
29
proudgeekdad
8 Авг 2008 в 17:11
VB полон подобных вещей, пытаясь сделать его «похожим на английский» и удобным для людей, которые привыкли к языкам, которые часто используют () и {}. А с другой стороны, как вы, наверное, уже знаете, в большинстве случаев вы можете использовать () с вызовами функций, если хотите, но не обязательно.
Я предпочитаю IsNothing () … но использую C и C #, так что это как раз то, что удобно. И я думаю, что это более читабельно. Но выбирайте то, что вам удобнее.
4
Andrew Morton
14 Фев 2021 в 19:24
Я склоняюсь к альтернативе «Is Nothing», прежде всего потому, что она кажется более объектно ориентированной.
Конечно, Visual Basic не является получил ключевое слово Ain’t.
4
Andrew Morton
19 Фев 2021 в 20:57
Изначально я использовал IsNothing, но постепенно перехожу к использованию Is Nothing в новых проектах, в основном для удобства чтения. Единственный раз, когда я придерживаюсь IsNothing, это если я поддерживаю код, в котором он используется повсюду, и хочу оставаться последовательным.
1
Chris Tybur
8 Авг 2008 в 17:24
Is Nothing требует объекта, которому было присвоено значение Nothing. IsNothing () может принимать любую переменную, которая не была инициализирована, в том числе числового типа. Это полезно, например, при проверке того, был ли передан необязательный параметр.
-2
ybacou
6 Мар 2016 в 07:23
Конструкторы
Инициализирует новый экземпляр класса NullReferenceException, устанавливая в качестве значения свойства нового экземпляра системное сообщение с описанием ошибки: «При запросе экземпляра объекта обнаружено значение NULL». Это сообщение учитывает культуру текущей системы. |
|
Инициализирует новый экземпляр класса NullReferenceException с сериализованными данными. |
|
Инициализирует новый экземпляр класса NullReferenceException с указанным сообщением об ошибке. |
|
Инициализирует новый экземпляр класса NullReferenceException указанным сообщением об ошибке и ссылкой на внутреннее исключение, вызвавшее данное исключение. |
Пути объектов / Вложенные
Код только тестирует одновременно, и может также быть формой. Средство , чтобы проверить всю цепочку или путь объектов по одному за раз:
это важно. Последующие тесты не будут выполняться после первого условия
Это позволяет коду безопасно «сверлить» на объект (ы) один «уровень» за раз, оценивая только после (и если) определено как действительное. Цепочки объектов или пути могут быть довольно длинными при кодировании сложных объектов:
Невозможно ссылаться на что-либо «вниз по течению» объекта. Это также относится к элементам управления:
Здесь или может быть Sub Form_Load (…_ ‘… Dim name As String = NameBoxes (2) .Text’ NRE ‘…’ Больше кода (который, скорее всего, не будет выполнен) ‘… End Sub или элемент может не существовать.
Нижняя линия
Вы пытаетесь использовать что-то, что есть (или в VB.NET). Это означает, что вы либо установили его , либо никогда не устанавливали его вообще.
Как и все остальное, все проходит. Если в методе «A», может быть , что метод «B» прошел к методу «A».
могут иметь разные значения:
Объектные переменные неинициализируются и, следовательно, указывают на InvalidOperationException. В этом случае, если вы обращаетесь к свойствам или методуNullReferenceException для таких объектов, это вызывает a .
Разработчик с помощью намеренно , чтобы указать , что нет смысла доступного значения
Обратите внимание, что C # имеет int b; cept of if (a.HasValue) {b = a.Value; } способные типы данных для переменных (например, таблицы базы данных могут иметь (a! = null) {b = a;} способное исключение fielNullReferenceException) — вы можете назначить им указать, что в нем нет значения, например, где знак вопроса указывает разрешено хранить значение null в переменной. Вы можете проверить это либо с помощью, либо с
Переменные, доступные в ToUpper (), как этот пример, позволяют получить доступ к значению через явное или просто нормальное значение . Обратите внимание, что доступ к нему через throws вместо a if is — вы должны сделать проверку заранее, то есть, если у вас есть другой on-var r1 = ref1; var r2 = r1.ref2; var r3 = r2.ref3; r3.member, то вы должны делать присваивания вроде или короче .
В остальной части этой статьи более подробно рассматриваются ошибки, которые часто делают многие программисты, которые могут привести к .
Свойства
Возвращает коллекцию пар «ключ-значение», предоставляющую дополнительные сведения об исключении. (Унаследовано от Exception) |
|
Получает или задает ссылку на файл справки, связанный с этим исключением. (Унаследовано от Exception) |
|
Возвращает или задает HRESULT — кодированное числовое значение, присвоенное определенному исключению. (Унаследовано от Exception) |
|
Возвращает экземпляр класса Exception, который вызвал текущее исключение. (Унаследовано от Exception) |
|
Возвращает сообщение, описывающее текущее исключение. (Унаследовано от Exception) |
|
Возвращает или задает имя приложения или объекта, вызывавшего ошибку. (Унаследовано от Exception) |
|
Получает строковое представление непосредственных кадров в стеке вызова. (Унаследовано от Exception) |
|
Возвращает метод, создавший текущее исключение. (Унаследовано от Exception) |