Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Типы, допускающие неопределенные значения
Инициализация переменных позволяет в момент объявления каждой переменной дать значение, принадлежащее множеству возможных значений данного типа. Тем самым исключается возможность работы с неопределенными значениями переменных. Однако для ссылочных типов возможным значением объектов является значение null, задающее неопределенную ссылку. Конечно, попытка вызвать метод или свойство объекта со значением null не приведет к успеху и возникнет ошибка периода выполнения. Тем не менее, полезно для ссылочных типов иметь null в качестве возможного значения. Для значимых типов значение null не входит в множество возможных значений. Но в ряде ситуаций полезно, чтобы переменная значимого типа имела неопределенное значение. Например, число в базе данных и число в языке программирования имеют важное отличие в своих характеристиках, поскольку число в базе данных может быть null. Число в С# не может быть null. Проблема существует не только с базами данных, но также с отображением данных XML на типы.NET. Язык C# позволяет из любого значимого типа данных построить новый тип, отличающийся лишь тем, что множество возможных значений дополнено специальным значением null. Так построенные типы данных называются типами, допускающими неопределенное значение (Nullable Types). Если построен тип T, то тип, допускающий неопределенные значения, определяется следующим образом: System.Nullable< T>Чаще используется эквивалентная, но более простая форма записи - T?Переменные таких типов могут получать значение null либо в результате присваивания, либо в процессе вычислений. Понятно, что если при вычислении выражения один из операндов будет иметь значение null, то и результат вычисления выражения будет иметь то же значение null. Над переменными этого типа определена специальная операция склеивания: A?? BРезультатом вычисления этого выражения будет операнд А, если значение А не равно null, и В, если первый операнд равен null. Рассмотрим выполнение преобразований между типами Т? и Т. Очевидно, что преобразование из типа Т в тип Т? - безопасное преобразование и потому может выполняться неявно. В другую сторону преобразование является опасным и должно выполняться явно, например, путем кастинга - приведения к типу. Рассмотрим некоторые примеры работы с переменными подобных типов. В этом фрагменте вводятся переменные типа int? и int. Демонстрируется безопасное преобразование из типа int в тип int? и выполнение операции?? - операции склеивания. Рассмотрим следующий фрагмент тестового метода: //x = (int)x1; y = (int)y1; Console.WriteLine(" x = {0}, y = {1}", x, y); z1 = x1 * y?? y1; y1 = z1 - y1; Console.WriteLine(" x1 = {0}, y1 = {1}, z1 = {2}", x1, y1, z1);Первая строка фрагмента закомментирована, поскольку попытка явного приведения типа переменной со значением null приведет к ошибке периода выполнения. В следующей строчке такое приведение успешно выполняется, поскольку переменная y1 имеет значение, допустимое для типа int. Заметьте, что операция?? имеет более низкий приоритет, чем операция умножения, поэтому первый операнд этой операции будет иметь значение null и z1 получит значение y1. В следующем фрагменте демонстрируются оба эквивалентных способа задания типа double, допускающего неопределенные значения: System.Nullable< double> u = x + x1; double? v = y + y1, w; w = u?? v + y1; Console.WriteLine(" u = {0}, v = {1}, w = {2}", u, v, w); Единственное дополнение к типу Т, определенное Nullable< T>, состоит булевском поле hasValue, которое определяет, установлено значение или же оно равно null. Помимо этого, обобщенная структура определяет доступные только для чтения свойства HasValue и Value, а также перегрузки некоторых операций. Перегрузка операции приведения Nullable< T> к Т определена явно, так как она может генерировать исключение в случае, если hasValue равно false. Перегрузка операции для приведения к Nullable< T> определена неявно, потому что она всегда успешна.
|