Классы и объекты C#: значение null

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

Классы в C#, как известно, относятся к ссылочным типам данных. Отличием ссылочных типов от типов значений состоит в том, что переменные ссылочных типов могут принимать значение null. Сегодня мы поговорим подробно про это значение в C# и о том, как можно осуществить проверку на null объектов C#.

Как известно, строки в C# также относятся к классам, поэтому обе представленных ниже операции могут быть выполнены без ошибок компиляции:

object o = null;
string s = null;

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

double d = null;
Ошибка CS0037 Не удается преобразовать значение NULL в «double», поскольку этот тип значений не допускает значение NULL

Оператор ??

Про этот оператор мы не говорили, когда разбирали логические операторы C#. Оператор ?? называется оператором null-объединения. Обычно, оператор null-объединения используется для того, чтобы установить для переменных ссылочного типа значение по умолчанию.

Принцип действия оператора null-объекдинения: оператор ?? возвращает левый операнд, если этот операнд не равен null. Иначе вычисляется правый операнд и возвращается его значение. То есть, слева от ?? всегда должна быть переменная ссылочного типа, т.е. «уметь» принимать значение null, например:

object x = null;
object y = x ?? "Переменной X присвоено значение null";
Console.WriteLine(y);

object z = 200;
object t = z ?? 44; //значение t = 200
Console.WriteLine(t);

В примере с объектов x на экран будет выведена строка «Переменной X присвоено значение null» так как x у нас равен null. Во втором случае, с переменной z на экран будет выведено значение 200 так как переменной z присвоено значение отличное от null.

При этом, мы не можем выполнить такую проверку:

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

Visual Studio сразу выдаст ошибку:

Ошибка CS0019 Оператор «??» невозможно применить к операнду типа «int» и «int».

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

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

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

class User
{
    public Phone Phone { get; set; }
}

class Phone
{
    public Company Company { get; set; }
}

class Company
{
    public string Name { get; set; }
}

Здесь объект User содержит ссылку на объект Phone, который, в свою очередь, содержит ссылку на объект Company. Теоретически, мы можем получить из объекта User название компании, например:

User user = new User();
Console.WriteLine(user.Phone.Company.Name);

Так как мы использовали конструктор по умолчанию, то свойство Phone не определено (имеет значение null) и, соответственно, Company тоже равно null. Поэтому, если мы попытаемся получить значение Company, то столкнемся с исключением NullReferenceException. Чтобы избежать такой ошибки мы могли бы использовать условный оператор if для проверки на null свойств у User и Phone, например:

User user = new User();

if(user!=null)
{
    if(user.Phone!=null)
    {
        if (user.Phone.Company != null)
        {
            string companyName = user.Phone.Company.Name;
            Console.WriteLine(companyName);
        }
    }
}

В итоге код будет работать, исключения не возникнет, но многоуровневая конструкция с нагромождением if наш код не красит, поэтому её можно сократить и написать вот так, используя наши знания по логическим операциям C#:

if(user!=null && user.Phone!=null && user.Phone.Company!=null)
{
    string companyName = user.Phone.Company.Name;
    Console.WriteLine(companyName);
}

Здесь мы уже задействовали условное логическое И. Конструкция, в итоге, получилась намного проще, но все равно довольно большой. Чтобы ее упростить, в C# имеется оператор условного null:

string companyName = user?.Phone?.Company?.Name;

Выражение ?. — это оператор условного null. В коде выше последовательно проверяется равен ли объект user и вложенные объекты значению nullи, если на каком-то этапе один из объектов окажется равным null, то companyName будет иметь значение по умолчанию, то есть null. Опять же, чтобы не получать в итоге на выходе null, можно объединить операторы ?? и ?. и написать проверку следующим образом:

User user = new User();
string companyName = user?.Phone?.Company?.Name ?? "не установлено";
Console.WriteLine(companyName);

Оператор ??=

Начиная с C# 8.0 можно использовать оператор присваивания объединения (=) со значением null.

Оператор ??= используется для присваивания значения правого операнда левому только в том случае, если левый операнд принимает значение null.

Оператор ??= не выполняет оценку своего операнда справа, если его операнд слева имеет значение, отличное от null. Например:

List<int> numbers = null;
(numbers ??= new List<int>()).Add(5);
Console.WriteLine(numbers[0]);

Так как объект numbers имел значение null, то, при использовании оператора ??= будет создан объект типа List<int> и в список будет добавлено число 5.

Итого

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

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
guest
0 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии