Главная » C# » Нулевые типы в Visual C# (Sharp)

0

В  .NET null означает отсутствие значения,  и  мы  все знаем, что это означает,  не так ли?  Например,  использование  null демонстрируется  в  следующем  коде:

Object value = null; if (value == null) {

Console.WriteLine("Yup a null.");

}

Пример демонстрирует очевидное и не делает ничего полезного. Если бы была предпринята попытка вызвать  метод  object.Tostringo, то  было  бы  сгенерирово исключение. Таким  образом, данный  код создает переменную value, которая  ни на что не ссылается и не имеет значения. Такой код работает, потому что в примере используется ссылочный тип .NET. Теперь давайте посмотрим, что случится, когда нулевое  значение  присваивается  нулевому типу:

int value = 0;  if (value == 0) {

Console.WriteLine("Yup a null?");

}

На этот раз, тип переменной value не object, a int, а переменной value присвоено значение 0, чтобы указывать  значение null. Я уже слышу, как многие из читателей возражают, что о ! = null. Но в языках программирования С++ и С null и 0 имеют одно  и то же  контекстное значение.

В .NET 2.0 и конкретно в С# имеется новый конструктив программирования, назающийся   нулевым   типом   (nullable   type).   Нулевой   тип   решает   проблему,   когда

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

В С# нулевой тип применяется для определения переменной, имеющей состояние null. В примере с обычным типом, целочисленной переменной было присвоено значение 0, но было бы уместнее присвоить значение null. Но обычным типам нельзя присваивать значение null, т. е. отсутствие значения, им требуется присваать какое-то действительное значение.

Объявление struct в следующем примере дополнительно демонстрирует огранения обычных типов:

struct ExampleStructure { int value;

}

ExampleStructure ex = null;

Структура ExampleStructure определяется посредством ключевого слова  struct. Это означает, что структура ExampleStructure обычного типа. Следующая строка кода, где переменной ех присваивается значение null, вызовет ошибку компилята. Структуре нельзя присвоить значение null, т. к. она относится к обычному ту. Это странное ограничение, т. к. структуры во многом сходны со ссылочными типами. Присваивание структуре значения по умолчанию при создании экземпляра не всегда будет правильным решением, т. к. члены данных могут не иметь значия по умолчанию.

Нулевые типы предоставляют обычным типам (например, структурам) возмоость вести себя, как ссылочные типы. В С# нулевой тип определяется добавленм знака вопроса после объявления типа:

ExampleStructure? ex = null;

Таким образом, нулевые типы позволяют присваивать значение null обычным там. Чтобы сделать это возможным, компилятор С# преобразует синтаксис С# для использования  стандартной  библиотеки  класса  Nullable. Вместо  использования нотации нулевого типа, можно прямо использовать тип system.Nuliableo: System.Nullable<ExampleStructure> ex = null;

Рассмотрим другой пример, в котором не используется нулевой тип:

int unknownl = 0; int knownl = 10;

int resultl = unknownl + knownl;

ExampleStructure? unknown2 = new ExampleStructure(0); ExampleStructure known2 = new ExampleStructure(10); int result2 = unknown2.value + known2.value;

В примере целочисленная переменная unknowni представляет  неизвестное значие, а переменная unknown2 типа Examplestructure — неизвестное значение типа struct. Неизвестные переменные подразумевают, что их значения не могут быть определены. Но хотя значения переменных неизвестны, им необходимо присвоить какие-либо известные значения. В примере с целочисленной переменной это ознает использование 0. А в случае с Examplestructure— создание экземпляра Examplestructure. Когда переменным присвоены значения, с выполнением оперий сложения  не будет никаких проблем. Но имеется проблема с этим  подходом, а именно: он неправильный. Результатом любой операции над известным и неиестным значениями должно быть неизвестное значение.

Проблема выполнения операций над неизвестными значениями решается  с  помью нулевых типов, как показано в следующем коде:

int? unknowni = null; int knownl = 10;

int resultl = (int)unknowni + knownl;

Examplestructure? unknown2 = null;  Examplestructure known2 = new Examplestructure(10);

int result2 = ((Examplestructure)unknown2).value + known2.value;

В данном модифицированном примере unknowni и unknown2 являются переменни нулевого типа, и им присвоено значение null, чтобы указать неизвестное стояние. Для выполнения операций сложения необходимо произвести небольшую модификацию сложения, а именно осуществить приведение к типу. Код, исполующий нулевые типы, функционально идентичен коду, который использует толо обычные типы. Разница состоит в том,  что  при попытке выполнить  операцию сложения генерируется исключение System. invalidOperation, указывающее, что значения несовместимы, и поэтому операцию нельзя выполнить. Такое поведение является правильным и ясно иллюстрирует надобность в нулевых типах.

ПРИМЕЧАНИЕ

Нулевые типы не предназначены для  совместного  использования  со  ссылочными типами. Они используются  с обычными типами,  и другой  причины для  их применения не  существует.

Источник: Гросс  К. С# 2008:  Пер. с англ. — СПб.:  БХВ-Петербург, 2009. — 576 е.:  ил. — (Самоучитель)

По теме:

  • Комментарии