Как проверить переменную на пустоту c
Перейти к содержимому

Как проверить переменную на пустоту c

  • автор:

Ответ на «Как можно проверить переменную типа char на «пустоту»»

char в C# — это value type, он не может иметь пустое значение, поэтому такая проверка не имеет смысла. Неинициализированная переменная типа char содержит его значение по умолчанию (символ \0 ). Если вам нужен тип, который может хранить либо символ, либо специальное пустое значение, смотрите в сторону Nullable types

Content is retrieved from StackExchange API.

Auto-generated by ruso-archive tools.

Back to top Stack Overflow answers (published from sources in GitHub repository). Copyright (c) 2020, MSDN.WhiteKnight. Content licensed under BSD 3-Clause License.
Generated by DocFX

Как проверить переменную на пустоту c

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

void PrintUpper(string? text) < if (text!=null) < Console.WriteLine(text.ToUpper()); >>

В данном случае если параметр text не равен null, то вызываем у строки метод ToUpper() , который переводит символы строки в верхний регистр.

Кроме того, с помощью оператора is мы можем проверить значение объекта:

объект is значение

Если объект слева от оператора is имеет значение справа от оператора. тогда оператор is возвращает true , иначе возвращается false

Например, проверка параметра/переменной на значение null:

void PrintUpper(string? text)

Или, наоборот, с помощью is not можно проверить отсутствие значения:

void PrintUpper(string? text)

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

void PrintUpper(string? text)

Подобные проверки еще называются null guard или условно говоря «защита от null».

Оператор ??

Оператор ?? называется оператором null-объединения . Он применяется для установки значений по умолчанию для типов, которые допускают значение null:

левый_операнд ?? правый_операнд

Оператор ?? возвращает левый операнд, если этот операнд не равен null . Иначе возвращается правый операнд. При этом левый операнд должен принимать null. Посмотрим на примере:

string? text = null; string name = text ?? "Tom"; // равно Tom, так как text равен null Console.WriteLine(name); // Tom int? personid = id ?? 1; // равно 200, так как id не равен null Console.WriteLine(personid); // 200

Но мы не можем написать следующим образом:

int x = 44; int y = x ?? 100;

Здесь переменная x представляет значимый тип int и не может принимать значение null, поэтому в качестве левого операнда в операции ?? она использоваться не может.

Также можно использовать производный оператора ??=

string? text = null; text ??= "Sam"; // аналогично // text = text ?? "Sam"; Console.WriteLine(text); // Sam int? ??= 1; // аналогично //id = id ?? 1; Console.WriteLine(id); // 100

Оператор условного null

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

class Person < public Company? Company < get; set; >// место работы > class Company < public string? WebSite < get; set; >// веб-сайт компании >

Объект Person представляет человека. Его свойство Company представляет компанию, где человек работает. Но человек может не работать, поэтому свойство Company имеет тип Company? , то есть может иметь значение null.

Класс Company в свою очередь содержит свойство WebSite, которое представляет веб-сайт компании. Но у компании может и не быть собственного веб-сайта. Поэтому это свойство имеет тип string? , то есть также допускает значение null.

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

void PrintWebSite(Person? person) < if (person != null) < if(person.Company != null) < if(person.Company.WebSite != null) < Console.WriteLine(person.Company.WebSite.ToUpper()); >> > > class Person < public Company? Company < get; set; >// место работы > class Company < public string? WebSite < get; set; >// веб-сайт компании >

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

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

void PrintWebSite(Person? person) < if (person != null && person.Company != null && person.Company.WebSite != null) < Console.WriteLine(person.Company.WebSite.ToUpper()); >>

Конструкция намного проще, но все равно получается довольно большой. И чтобы ее упростить, в C# есть оператор условного null (Null-Conditional Operator) — оператор ?. :

объект?.компонент

Если объект не равен null , то происходит обращение к компоненту объекта — полю, свойству, методу. Если объект представляет значение null, обращение к компаненту метода не происходит.

Применим данный оператор, изменив предыдущий пример:

void PrintWebSite(Person? person)

Таким образом, если person не равен null, то происходит обращение к его свойству Company. Если свойство Company не равно null, то идет обрашение к свойству WebSite объекта Company. Если свойство WebSite не равно null, то идет обращение к методу ToUpper() .

Как проверить переменную на пустоту?

Но если отправить переменную, но она будет пуста, то всё равно выполняется TRUE.

Объясните как поправить данный момент. Спасибо.

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

Комментировать
Решения вопроса 1

Nukk

MeteorJS евангелист

!empty вместо empty, ибо в данном случае если переменная пуста — if срабатывает.
в случае с !empty (если не пуста) — получите то, что нужно

Пустое значение переменной

А что вы понимаете под выражением «пуста»? Она не инициализировалась ничем в явном виде (в духе int a; )?

22 фев 2016 в 9:17
Если вам дан исчерпывающий ответ, отметьте его как верный (галка напротив выбранного ответа).
23 фев 2016 в 7:49

5 ответов 5

Сортировка: Сброс на вариант по умолчанию

Переменные встроенных типов ( int , double и т. д.) не могут быть пустыми в принципе, даже если вы их не инициализировали. В любом случае переменная будет иметь какое-либо значение.

При объявлении переменной (например, int a; ) ей выделяется память, если переменную не инициализировать, то значение переменной будет равно тому мусору, который был в памяти до этого. Поэтому пуста ли переменная спрашивать некорректно, и так же считается хорошим правилом всегда инициализировать переменные значением при объявлении.

Отслеживать
ответ дан 22 фев 2016 в 9:08
Yuriy Orlov Yuriy Orlov
1,996 10 10 серебряных знаков 15 15 бронзовых знаков

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

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

Вы не можете проверить переменную локально. Вы должны сами убедиться в том, что все переменные правильно инициализированы. Компилятор C++ ничего не сделает за вас, он считает вас очень взрослым и очень ответственным. (В отличие от других языков, которые контролируют вас более плотно.)

Отслеживать
ответ дан 22 фев 2016 в 10:04
207k 29 29 золотых знаков 295 295 серебряных знаков 529 529 бронзовых знаков

Кстати, для типа unsigned char UB не возникает при использовании неопределенного (неинициализированного) значения. См. ISO/IEC 14882:2014 8.5/12.

22 фев 2016 в 13:14

@alexolut: Исходя из текста, не «не возникает», а «не всегда возникает». Там есть прекрасный поясняющий пример.

22 фев 2016 в 14:59
Отслеживать
29.1k 14 14 золотых знаков 61 61 серебряный знак 120 120 бронзовых знаков
ответ дан 22 фев 2016 в 9:33
31.2k 13 13 золотых знаков 98 98 серебряных знаков 159 159 бронзовых знаков

Нельзя никак определить инициализирована ли переменная фундаментального типа или нет. Т.к. отсутствие инициализации подразумевает (в частном случае) наличие любого случайного (мусорного) значения.

При этом компилятор в отладочном режиме всё же может писать в такие переменные какое-то определенное значение (в том числе и ноль), по которому можно косвенно понять, что переменная не была инициализирована. Косвенно, потому, что вполне возможно инициализировать переменную явно точно таким же значением.

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

Отслеживать
ответ дан 22 фев 2016 в 9:07
29.1k 14 14 золотых знаков 61 61 серебряный знак 120 120 бронзовых знаков

Причем на эти предупреждения нельзя полагаться, например такой код: int a; bool b = false; if (b) a = 0; a++; может не выдать никаких предупреждений.

22 фев 2016 в 9:12

@andy.37 clang кстати умеет. Но вообще, наличие такой диагностики не является обязательным по Стандарту, поэтому я и написал, что может сообщить , но не обязан.

22 фев 2016 в 9:36

по той же причине я написал «может не выдать». Наверное, следовало написать «не следует полагаться на отсутствие предупреждений такого рода». В общем, консенсус))) П.С. Куда написать вопрос по работе собственно сайта ruSO?

22 фев 2016 в 10:41
@andy.37 тут есть мета секция на сайте. Туда и писать.
22 фев 2016 в 10:57

Тип int может предоставить 2^32 = 4*10^9 различный объектов.

ObjInt =

При старте функции в стеке эта переменная может быть инициализирована неопределёнными значениями. От obj1 до obj4294967296. Если у вас объектов меньше (например 1000) то можно выбрать состояние obj4294967296 и его назвать пусто. Но всё равно всем объектам нужно назначить это состояние.

int i , j ; i = -1 ; // пусто j = 5 ; 

Другой вариант если состояний будет максимум 4294967296. Тогда 4294967296+1=4294967297 состояний не будет вмещаться в int физически. Исправить это можно очень многими способами. Например дополнительной переменной, означающим этот признак пустоты. И опять при старте функции этот признак пустоты будет заполнен случайным (неопределённым) значением. Его нужно выставить сразу.

bool ie = true ; bool je = true ; int i , j ; i = -1 ; ie = false ; j = 5 ; je = false ; 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *