Шрифт:
Интервал:
Закладка:
Например, с помощью свойства 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");
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})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).
- Понимание SQL - Мартин Грубер - Базы данных