Программирование >>  Программирование с использованием ajax 

1 ... 105 106 107 [ 108 ] 109 110 111 ... 396


Бывают ситуации, и возникают они гораздо чаще, чем может показаться (особенно во время работы с базами данных), в которых полезно иметь тип-значение, способный быть нулевым. Обобщения предлагают способ для получения такого типа, и заключается он в использовании типа System.Nullable<T>, как показано в следующем примере:

System.Nullable<int> nullableint;

В этой строке кода объявляется переменная по имени nullableint, которая может иметь любое такое же значение, как и переменная int, плюс значение null. Это позволяет использовать код, подобный показанному ниже:

nullableint = null;

Если бы nullableint не была переменной типа int, тогда скомпилировать предыдущий код было бы невозможно.

Предыдущая операция присваивания эквивалента приведенной ниже:

nullableint = new System.Nullable<int> ();

Как и любую другую переменную, данную переменную нельзя использовать безо всякой предварительной инициализации, будь то присваивание значения null (с применением показанного выше синтаксиса) или какого-то другого значения.

Нулевые типы можно проверять на предмет того, действительно ли в них содержится значение null, точно так же, как и ссылочные типы:

if (nullableint == null)

В качестве альтернативного варианта можно использовать свойство HasValue: if (nullableint.HasValue)

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

Еще значение нулевого типа можно узнавать с помощью свойства Value. Если HasValue возвращает true, это означает, что значением свойства Value точно не является null. Но если HasValue возвращает false, тогда это означает, что переменной было присвоено значение null и поэтому получение доступа к Value закончится генерацией исключения System. InvalidOperationException.

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

int? nullableint;

Здесь синтаксис int? представляет собой простой сокращенный вариант синтаксиса System.Nullable<int>, но является гораздо более удобным для восприятия, и потому в последующих разделах будет применяться именно он.



Операции и нулевые типы

в случае простых типов вроде int для работы со значениями могут использоваться операции, подобные +, - и т.д. В случае эквивалентных им нулевых типов дело не меняется: значения, содержащиеся в нулевых типах, неявно преобразовываются в требуемый тип, и далее для работы с ними спокойно используются подходящие операции. То же самое касается и структур с предоставленными операциями:

int? opl = 5;

int? result = opl * 2;

Обратите внимание, что здесь переменная result тоже относится к типу int?. Поэтому следующий код не будет компилироваться:

int? opl = 5;

int result = opl * 2;

Чтобы исправить это, необходимо выполнить явное преобразование:

int? opl = 5;

int result = (int) opl * 2;

Данный код будет работать, но только в случае присваивания opl какого-нибудь числового значения: в случае же присваивания opl значения null будет генерироваться исключение System.InvalidOperationException.

Это вызывает вполне естественный вопрос о том, что же происходит, когда какое-то одно или оба значения в процессе вычисления операции оказываются равными null, как значение opl в предыдущем коде? Ответ таков: в случае всех простых нулевых типов, кроме bool?, вычисление операции завершается возвратом значения null, что на обычном языке можно выразить словами не получается вычислить . В случае конструкций для обработки подобных ситуаций можно определять свои собственные операции (как будет показано позже в этой главе), а в случае типа bool? существуют предопределенные операции & и , которые способны возвращать не null значения и показаны в табл. 12.1.

Таблица 12.1. Возможные результаты операций & и для операндов типа bool? opl ор2 opl & ор2 opl I ор2

true

true

true

true

true

false

false

true

true

null

null

true

false

true

false

true

false

false

false

false

false

null

false

null

null

true

null

true

null

false

false

null

null

null

null

null

Результаты, приведенные в этой таблице, вполне понятны с логической точки зрения: если имеется достаточно информации для выяснения ответа в ходе вычисления и без знания значения одного из операндов, тогда нет никакой разницы, является значением этого операнда null или нет.



Операция ??

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

opl ?? ор2

opl == null ? ор2 : opl

В этом коде opl может представлять собой выражение любого типа, в том числе и ссылочного, а также, что более важно, нулевого типа. Это означает, что операцию ?? можно использовать для предоставления тех значений, которые должны использоваться по умолчанию в случае, если нулевой тип равен null, как показано ниже:

int? opl = null;

int result = opl * 2 ?? 5;

Поскольку в этом примере opl равно null, opl * 2 тоже будет равно null. Однако операция ?? обнаруживает это и присваивает result значение 5. Очень важно обратить здесь внимание на то, что выполнять никакое явное преобразование для помещения результата в переменную result, являющуюся переменной целочисленного типа, не требуется. Операция ?? выполняет это преобразование сама. В качестве альтернативного варианта результат вычисления ?? можно без проблем поместить и в int?:

int? result = opl * 2 ?? 5;

Это делает операцию ? ? универсальной операцией для применения при работе с нулевыми переменными, а также удобным способом для предоставления значений по умолчанию, который позволяет не прибегать ни к добавлению какого-то блока кода в структуру if, ни к использованию тернарной операции, столь часто вызывающей путаницу

В следующем практическом занятии предоставляется возможность поэкспериментировать с нулевыми типами на примере типа Vector.

Практическое занятие Нулевые типы

1. Создайте новый проект типа консольного приложения по имени СЫ2Ех01 и сохраните его в каталоге С: \BegVCSharp\Chapterl2.

2. Добавьте в него новый класс Vector в файле Vector. cs.

3. Измените код в файле Vector. cs следующим образом:

public class Vector {

public double? R = null; public double? Theta = null; public double? ThetaRadians {

get {

Преобразование градусов в радианы, return (Theta * Math.PI / 180.0);



1 ... 105 106 107 [ 108 ] 109 110 111 ... 396

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика