Рейтинговые книги
Читем онлайн Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 59 60 61 62 63 64 65 66 67 ... 407
удобно при работе с реляционными базами данных, поскольку в таблицах баз данных довольно часто встречаются столбцы, для которых значения не определены. Без концепции типов данных, допускающих null, в C# не было бы удобного способа для представления числовых элементов данных без значений.

Чтобы определить переменную типа, допускающего null, необходимо добавить к имени интересующего типа данных суффикс в виде знака вопроса (?). До выхода версии C# 8.0 такой синтаксис был законным только в случае применения к типам значений (более подробные сведения ищите в разделе "Использование ссылочных типов, допускающих null" далее в главе). Подобно переменным с типами, не допускающими null, локальным переменным, имеющим типы, которые допускают null, должно присваиваться начальное значение, прежде чем ими можно будет пользоваться:

static void LocalNullableVariables()

{

  // Определить несколько локальных переменных

  // с типами, допускающими null

  int? nullableInt = 10;

  double? nullableDouble = 3.14;

  bool? nullableBool = null;

  char? nullableChar = 'a';

  int?[] arrayOfNullableInts = new int?[10];

}

Использование типов значений, допускающих null

В языке C# система обозначений в форме суффикса ? представляет собой сокращение для создания экземпляра обобщенного типа структуры System.Nullable<T>. Она также применяется для создания ссылочных типов, допускающих null, но ее поведение несколько отличается. Хотя подробное исследование обобщений мы отложим до главы 10, сейчас важно понимать, что тип System.Nullable<T> предоставляет набор членов, которые могут применяться всеми типами, допускающими null.

Например, с помощью свойства HasValue или операции != можно программно выяснять, действительно ли переменной, допускающей null, было присвоено значение null. Значение, которое присвоено типу, допускающему null, можно получать напрямую или через свойство Value. Учитывая, что суффикс ? является просто сокращением для использования Nullable<T>, предыдущий метод LocalNullableVariables() можно было бы реализовать следующим образом:

static void LocalNullableVariablesUsingNullable()

{

  // Определить несколько типов, допускающих null,

  // с применением Nullable<T>.

  Nullable<int> nullableInt = 10;

  Nullable<double> nullableDouble = 3.14;

  Nullable<bool> nullableBool = null;

  Nullable<char> nullableChar = 'a';

  Nullable<int>[] arrayOfNullableInts = new Nullable<int>[10];

}

Как отмечалось ранее, типы данных, допускающие null, особенно полезны при взаимодействии с базами данных, потому что столбцы в таблицах данных могут быть намеренно оставлены пустыми (скажем, быть неопределенными). В целях демонстрации рассмотрим показанный далее класс, эмулирующий процесс доступа к базе данных с таблицей, в которой два столбца могут принимать значения null. Обратите внимание, что метод GetlntFromDatabase() не присваивает значение члену целочисленного типа, допускающего null, тогда как метод GetBoolFromDatabase() присваивает допустимое значение члену типа bool?

class DatabaseReader

{

  // Поле данных типа, допускающего null.

  public int? numericValue = null;

  public bool? boolValue = true;

  // Обратите внимание на возвращаемый тип, допускающий null.

  public int? GetIntFromDatabase()

  { return numericValue; }

  // Обратите внимание на возвращаемый тип, допускающий null.

  public bool? GetBoolFromDatabase()

  { return boolValue; }

}

В следующем коде происходит обращение к каждому члену класса DatabaseReader и выяснение присвоенных значений с применением членов HasValue и Value, а также операции равенства C# (точнее операции "не равно"):

Console.WriteLine("***** Fun with Nullable Value Types *****n");

DatabaseReader dr = new DatabaseReader();

/// Получить значение int из "базы данных".

int? i = dr.GetIntFromDatabase();

if (i.HasValue)

{

  Console.WriteLine("Value of 'i' is: {0}", i.Value);

                  // Вывод значения переменной i

}

else

{

  Console.WriteLine("Value of 'i' is undefined.");

                  // Значение переменной i не определено

}

// Получить значение bool из "базы данных".

bool? b = dr.GetBoolFromDatabase();

if (b != null)

{

  Console.WriteLine("Value of 'b' is: {0}", b.Value);

                  // Вывод значения переменной b

}

else

{

  Console.WriteLine("Value of 'b' is undefined.");

                  // Значение переменной b не определено

}

Console.ReadLine();

Использование ссылочных типов, допускающих null (нововведение в версии 8.0)

Важным средством, добавленным в версию C# 8, является поддержка ссылочных типов, допускающих значение null. На самом деле изменение было настолько значительным, что инфраструктуру .NET Framework не удалось обновить для поддержки нового средства. В итоге было принято решение поддерживать C# 8 только в .NET Core 3.0 и последующих версиях и также по умолчанию отключить поддержку ссылочных типов, допускающих null. В новом проекте .NET Core 3.0/3.1 или .NET 5 ссылочные типы функционируют точно так же, как в C# 7. Это сделано для того, чтобы предотвратить нарушение работы миллиардов строк кода, существовавших в экосистеме до появления C# 8. Разработчики в своих приложениях должны дать согласие на включение ссылочных типов, допускающих null.

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

Для указания способности иметь значение null в ссылочных типах, допускающих null, применяется тот же самый символ ?. Однако он не является сокращением для использования System.Nullable<T>, т.к. на месте Т могут находиться только типы значений. Не забывайте, что обобщения и ограничения рассматриваются в главе 10.

Включение ссылочных типов, допускающих null

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

• Контекст с заметками о допустимости значения null: включает/отключает заметки о допустимости null(?) для ссылочных типов, допускающих null.

• Контекст с

1 ... 59 60 61 62 63 64 65 66 67 ... 407
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен бесплатно.

Оставить комментарий