📚 Hub Books: Онлайн-чтение книгРазная литератураИнтернет-журнал "Домашняя лаборатория", 2007 №9 - Журнал «Домашняя лаборатория»

Интернет-журнал "Домашняя лаборатория", 2007 №9 - Журнал «Домашняя лаборатория»

Шрифт:

-
+

Интервал:

-
+
1 ... 350 351 352 353 354 355 356 357 358 ... 415
Перейти на страницу:
и наоборот, сложение и вычитание определено над точками и размерами, но не над точками, плавающий тип которых разными способами можно привести к целому. Ряд операций над этими структурами продемонстрирован в следующем примере:

public void TestPointAndSize()

{

    Point pt1 = new Point(3,5), pt2 = new Point(7,10), pt3;

    PointF pt4 = new PointF(4.55f,6.75f);

    Size sz1 = new Size(10,20), sz2;

    SizeF sz3 = new SizeF(10.3f, 20.7f);

    pt3 = Point.Round(pt4);

    sz2 = new Size (pt1);

    Console.WriteLine ("pt1: " + pt1);

    Console.WriteLine ("sz2 =new Size (pt1): " + sz2);

    Console.WriteLine ("pt4: " + pt4);

    Console.WriteLine("pt3 =Point.Round(pt4): " + pt3);

    pt1.Offset (5,7);

    Console.WriteLine ("pt1.Offset(5,7): + pt1);

    Console.WriteLine ("pt2: " + pt2);

    pt2 = pt2 + sz2;

    Console.WriteLine ("pt2= pt2 + sz2: " + pt2)

}//TestPointAndSize

Результаты его выполнения показаны на рис. 17.1

Рис. 17.1. Операции над точками и размерами

Отметим, что метод Tostring, определенный для этих структур, выдает строку со значениями полей в приемлемой для восприятия форме.

Еще раз о двух семантиках присваивания

В заключение разговора о ссылочных и развернутых типах построим класс CPoint, являющийся полным аналогом структуры Point. Не буду приводить описание этого класса — надеюсь, оно достаточно понятно. Ограничусь примером, в котором аналогичные действия выполняются над объектами, принадлежащими структуре Point и классу CPoint:

public void TestTwoSemantics()

{

    Console.WriteLine("Структуры: присваивание развернутого типа!");

    Point pt1 = new Point(3,5), pt2;

    pt2 = pt1;

    Console.WriteLine ("pt1: " + pt1);

    Console.WriteLine ("pt2=pt1: " + pt2);

    pt1.X +=10;

    Console.WriteLine ("pt1.X =pt1.X +10: " + pt1);

    Console.WriteLine ("pt2: " + pt2);

    Console.WriteLine("Классы: присваивание ссылочного типа!");

    CPoint cpt1 = new CPoint(3,5), cpt2; cpt2 = cpt1;

    Console.WriteLine ("cpt1: " + cpt1);

    Console.WriteLine ("cpt2=cpt1: " + cpt2);

    cpt1.X +=10;

    Console.WriteLine ("cptl.X =cpt1.X +10: " + cpt1);

    Console.WriteLine ("cpt2: " + cpt2);

}

Результаты вычислений показаны на рис. 17.2.

Рис. 17.2. Две семантики присваивания

Действия над объектами Point и CPoint выполняются аналогичные а результаты получаются разные: в конце вычислений pt1 и pt2 различны, a cpt1 и cpt2 совпадают.

Перечисления

Перечисление — это частный случай класса, класс, заданный без собственных методов. Перечисление задает конечное множество возможных значений, которые могут получать объекты класса перечисление. Поскольку у перечислений нет собственных методов, то синтаксис объявления этого класса упрощается — остается обычный заголовок и тело класса, содержащее список возможных значений. Вот формальное определение синтаксиса перечислений-.

[атрибуты][модификаторы] enum имя_перечисления[: базовый класс]

{список_возможных_значений}

Описание атрибутов отложим на последующие лекции. Модификаторами могут быть четыре известных модификатора доступа и модификатор new. Ключевое слово enum говорит, что определяется частный случай класса — перечисление. Список возможных значений задает те значения, которые могут получать объекты этого класса. Возможные значения должны быть идентификаторами; но допускаются в их написании и буквы русского алфавита. Можно указать также базовый для перечисления класс.

Дело в том, что значения, заданные списком, проецируются на плотное подмножество базового класса. Реально значения объектов перечисления в памяти задаются значениями базового класса, так же, как значения класса bool реально представлены в памяти нулем и единицей, а не константами true и false, удобными для их использования программистами в тексте программ. По умолчанию, базовым классом является класс int, а подмножество проекции начинается с нуля. Но при желании можно изменить интервал представления и сам базовый класс. Естественно, на базовый класс накладывается ограничение. Он должен быть одним из встроенных классов, задающих счетное множество (int, byte, long, другие счетные типы). Единственное исключение из этого правила — нельзя выбирать класс char в качестве базового класса. Как правило, принятый по умолчанию выбор базового класса и его подмножества вполне приемлем в большинстве ситуаций.

Приведу примеры объявлений классов-перечислений:

public enum Profession{teacher, engineer, businessman};

public enum MyColors {red, blue, yellow, black, white};

public enum TwoColors {black, white};

public enum Rainbow {красный, оранжевый, желтый, зеленый, голубой, синий, фиолетовый};

public enum Sex: byte {man=1, woman};

public enum Days: long {Sun,Mon,Tue,Wed,Thu, Fri, Sat};

Вот несколько моментов, на которые следует обратить внимание при объявлении перечислений:

• как и другие классы, перечисления могут быть объявлены непосредственно в пространстве имен проекта или могут быть вложены в описание класса. Последний вариант часто применяется, когда перечисление используется в одном классе и имеет атрибут доступа private;

• константы разных перечислений могут совпадать, как в перечислениях MyColors и TwoColors. Имя константы всегда уточняется именем перечисления-,

• константы могут задаваться словами русского языка, как в перечислении Rainbow;

• разрешается задавать базовый класс перечисления. Для перечисления Days базовым классом задан класс long;

• разрешается задавать не только базовый класс, но и указывать начальный элемент подмножества, на которое проецируется множество значений перечисления. Для перечисления Sex в качестве базового класса выбран класс byte, а подмножество значений начинается с 1, так что хранимым значением константы man является 1, a woman — 2.

Рассмотрим теперь пример работы с объектами — экземплярами различных перечислений:

public void TestEnum()

{

    //MyColors colorl = new MyColors(MyColors.blue);

    MyColors colorl= MyColors.white;

    TwoColors color2;

    color2 = TwoColors.white;

    //if (color1!= color2) color2 = color1;

    if(color1.ToString ()!= color2.ToString())

          Console.WriteLine ("Цвета разные: {0}, {1}",

            color1, color2);

     else Console.WriteLine("Цвета одинаковые: {0},

            {1}",color1, color2);

     Rainbow color3; color3 = (Rainbow)3;

     if (color3!= Rainbow.красный)color3 =Rainbow.красный;

     int num = (int)color3;

     Sex who = Sex.man;

     Days first_work_day = (Days) (long)l;

     Console.WriteLine ("color1={0}, color2={1},

            color3={2}",color1, color2, color3);

     Console.WriteLine ("who={0}, first_work_day={1}",

            who,first_work_day);

}

Данный пример иллюстрирует следующие особенности работы с объектами перечислений-.

• объекты перечислений нельзя создавать в объектном стиле с использованием операции new, поскольку перечисления не имеют конструкторов;

• объекты можно объявлять с явной инициализацией, как color1, или с отложенной инициализацией,

1 ... 350 351 352 353 354 355 356 357 358 ... 415
Перейти на страницу:

Комментарии

Обратите внимание, что комментарий должен быть не короче 20 символов. Покажите уважение к себе и другим пользователям!

Никто еще не прокомментировал. Хотите быть первым, кто выскажется?