Шрифт:
В следующем фрагменте кода переменной balance присваивается значение 123.75. double? balance = 123.75; double currentBalance; currentBalance = balance ?? 0.0;
Теперь переменная currentBalance содержит значение 123.75 переменной balance.
И еще одно замечание: выражение в правой части оператора ?? вычисляется толь ко в том случае, если выражение в левой его части не содержит значение. Этот факт демонстрируется в приведенной ниже программе. // Применение оператора ?? using System; class NullableDemo2 { // Возвратить нулевой остаток. static double GetZeroBal { Console.WriteLine("В методе GetZeroBalO."); return 0.0; } static void Main { double? balance = 123.75; double currentBalance; // Здесь метод GetZeroBal не вызывается, поскольку // переменная balance содержит конкретное значение. currentBalance = balance ?? GetZeroBal; Console.WriteLine(currentBalance); } }
В этой программе метод GetZeroBal не вызывается, поскольку переменная balance содержит конкретное значение. Как пояснялось выше, если выражение в ле вой части оператора ?? содержит конкретное значение, то выражение в правой его части не вычисляется. Обнуляемые объекты, операторы отношения и логические операторы
Обнуляемые объекты могут использоваться в выражениях отношения таким же образом, как и соответствующие объекты необнуляемого типа. Но они должны под чиняться следующему дополнительному правилу: когда два обнуляемых объекта срав ниваются в операциях сравнения <, >, <= или >=, то их результат будет ложным, если любой из обнуляемых объектов оказывается пустым, т.е. содержит значение null. В качестве примера рассмотрим следующий фрагмент кода. byte? lower = 16; byte? upper = null;
// Здесь переменная lower определена, а переменная upper не определена. if(lower < upper) // ложно
В данном случае проверка того, что значение одной переменой меньше значения другой, дает ложный результат. Хотя это и не совсем очевидно, как, впрочем, и следую щая проверка противоположного характера. if(lower > upper) // .. также ложно!
Следовательно, если один или оба сравниваемых обнуляемых объекта оказываются пустыми, то результат их сравнения всегда будет ложным. Это фактически означает, что пустое значение (null) не участвует в отношении порядка.
Тем не менее с помощью операторов == и != можно проверить, содержит ли обну ляемый объект пустое значение. Например, следующая проверка вполне допустима и дает истинный результат. if(upper == null) // ...
Если в логическом выражении участвуют два объекта типа bool?, то его результат может иметь одно из трех следующих значений: true (истинное), false (ложное) или null (неопределенное). Ниже приведены результаты применения логических опера торов & и | к объектам типа bool?. P Q P | Q P & Q true null true null false null null false null true true null null false null false null null null null
И наконец, если логический оператор ! применяется к значению типа bool?, ко торое является пустым (null), то результат этой операции будет неопределенным (null). Частичные типы
Начиная с версии 2.0, в C# появилась возможность разделять определение класса, структуры или интерфейса на две или более части с сохранением каждой из них в от дельном файле. Это делается с помощью контекстного ключевого слова partial. Все эти части объединяются вместе во время компиляции программы.
Если модификатор partial используется для создания частичного типа, то он принимает следующую общую форму: partial тип имя_типа { // ...
где имя_типа обозначает имя класса, структуры или интерфейса, разделяемого на ча сти. Каждая часть получающегося частичного типа должна указываться вместе с моди фикатором partial.
Рассмотрим пример разделения простого класса, содержащего координаты XY, на три отдельных файла. Ниже приведено содержимое первого файла.
partial class XY { public XY(int a, int b) { X = a; Y = b; } }
Далее следует содержимое второго файла. partial class XY { public int X { get; set; } }
И наконец, содержимое третьего файла. partial class XY { public int Y { get; set; } } В приведенном ниже файле исходного текста программы демонстрируется при менение класса XY.
// Продемонстрировать определения частичного класса. using System;
class Test { static void Main { XY xy = new XY (1, 2); Console.WriteLine(xy.X + + xy.Y); } } Для того чтобы воспользоваться классом XY, необходимо включить в компиля цию все его файлы. Так, если файлы класса XY называются xy1.cs, ху2.cs и ху3.cs, а класс Test содержится в файле test.cs, то для его компиляции достаточно ввести в командной строке следующее.
csc test.cs xy1.cs xy2.cs хуЗ.cs И последнее замечание: в C# допускаются частичные обобщенные классы. Но пара метры типа в объявлении каждого такого класса должны совпадать с теми, что указы ваются в остальных его частях. ## Частичные методы Как пояснялось в предыдущем разделе, с помощью модификатора partial мож но создать класс частичного типа. Начиная с версии 3.0, в C# появилась возможность использовать этот модификатор и для создания частичного метода в элементе данных частичного типа. Частичный метод объявляется в одной его части, а реализуется в дру гой. Следовательно, с помощью модификатора partial можно отделить объявление метода от его реализации в частичном классе или структуре. Главная особенность частичного метода заключается в том, что его реализация не требуется! Если частичный метод не реализуется в другой части класса или структуры, то все его вызовы молча игнорируются. Это дает возможность определить, но не вос требовать дополнительные, хотя и не обязательные функции класса. Если эти функции не реализованы, то они просто игнорируются. Ниже приведена расширенная версия предыдущей программы, в которой создает ся частичный метод Show. Этот метод вызывается другим методом, ShowXY. Ради удобства все части класса XY представлены в одном файле, но они могут быть распре делены по отдельным файлам, как было показано в предыдущем разделе.