Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Другие элементы меню 14 страница




private Rational(int a, int b, string t)

{

m = a; n = b;

}

Поскольку при перегрузке методов (в данном случае конструкторов) сигнатуры должны различаться, то пришлось ввести дополнительный аргумент t для избежания конфликтов. Поскольку конструктор закрытый, то гарантируется корректное задание аргументов при его вызове. Определим теперь константы класса, которые, как я уже говорил, задаются статическими полями с атрибутом readonly:

//Константы класса 0 и 1 - Zero и One

public static readonly Rational Zero, One;

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

static Rational()

{

Console.WriteLine("static constructor Rational");

Zero = new Rational(0, 1, "private");

One = new Rational (1, 1, "private");

}// Статический конструктор

Как это все работает? Статический конструктор вызывается автоматически один раз до начала работы с объектами класса. Он и задаст значения статических полей Zero, One, представляющих рациональные числа с заданным значением. Поскольку эти поля имеют атрибут static и readonly, то они доступны для всех объектов класса и не изменяются в ходе вычислений, являясь настоящими константами класса. Прежде чем привести пример работы с константами, давайте добавим в наш класс важные булевы операции над рациональными числами – равенство и неравенство, больше и меньше. При этом две последние операции сделаем перегруженными, позволяя сравнивать рациональные числа с числами типа double:

public static bool operator ==(Rational r1, Rational r2)

{

return ((r1.m ==r2.m)&& (r1.n ==r2.n));

}

public static bool operator!=(Rational r1, Rational r2)

{

return ((r1.m!=r2.m)|| (r1.n!=r2.n));

}

public static bool operator <(Rational r1, Rational r2)

{

return (r1.m * r2.n < r2.m* r1.n);

}

public static bool operator >(Rational r1, Rational r2)

{

return (r1.m * r2.n > r2.m* r1.n);

}

public static bool operator <(Rational r1, double r2)

{

return ((double)r1.m / (double)r1.n < r2);

}

public static bool operator >(Rational r1, double r2)

{

return ((double)r1.m / (double)r1.n > r2);

}

Наш последний пример демонстрирует работу с константами, булевыми и арифметическими выражениями над рациональными числами:

public void TestRationalConst()

{

Rational r1 = new Rational(2,8), r2 = new Rational(2,5);

Rational r3 = new Rational(4, 10), r4 = new Rational(3,7);

Rational r5 = Rational.Zero, r6 = Rational.Zero;

if ((r1!= Rational.Zero) && (r2 == r3))r5 = (r3+Rational.One)*r4;

r6 = Rational.One + Rational.One;

r1.PrintRational("r1: (2,8)"); r2.PrintRational("r2: (2,5)");

r3.PrintRational("r3: (4,10)"); r4.PrintRational("r4: (3,7)");

r5.PrintRational("r5: ((r3 +1)*r4)"); r6.PrintRational("r6: (1+1)");

}

Результаты работы этого примера показаны на рис. 16.6.

Рис. 16.6. Константы и выражения типа Rational

Вариант 1

43. Класс имеет:

q только один конструктор;

q только конструктор по умолчанию;

q не более одного статического конструктора;

q не более одного закрытого конструктора;

q несколько конструкторов с одинаковой сигнатурой.

44. Отметьте истинные высказывания:

q статические методы класса могут вызывать любые методы класса;

q все конструкторы класса вызываются только при выполнении операции new;

q свойства задаются для закрытых полей класса;

q каждый объект содержит набор из всех полей, определенных в классе.

45. Свойство класса:

q может иметь атрибут доступа private;

q может включать методы get и set;

q включает только один из методов get или set;

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

q обязательно должно быть указано для каждого закрытого поля класса.

Вариант 2

47. Объекты класса Rational могут быть созданы в клиентском классе:

q конструктором по умолчанию;

q конструктором с аргументами;

q закрытым конструктором;

q статическим конструктором.

48. Отметьте истинные высказывания:

q любые методы класса могут вызывать статические методы;

q конструкторы класса вызываются автоматически;

q у класса может быть только один индексатор

q класс не может иметь закрытых методов.

49. Поля класса:

q могут иметь любой из модификаторов доступа: public, private, protected, internal;

q могут иметь модификатор static;

q обычно закрываются;

q закрытые поля доступны методам класса.

Вариант 3

44. Тело класса может содержать описание:

q полей;

q методов;

q классов;

q интерфейсов;

q пространств имен;

q событий.

45. Отметьте истинные высказывания:

q статическое поле класса доступно в любом методе класса;

q статический конструктор класса вызывается автоматически;

q у класса может быть задано несколько свойств;

q у класса может быть задано несколько индексаторов;

q у класса может быть определено несколько операций.

46. Пусть p1, p2, p3 – переменные класса Rational. Отметьте правильно построенные конструкции:

q if(p1!= p2) p3 = p1+p2;

q p3 = p1+ p2 +1;

q p3 =(Rational.One + Rational.One)* p2 +p1;

q p3 +=Rational.One;

q p3++.

 

 

Лекция 17. Структуры и перечисления

Понятие развернутого и ссылочного типа. Структуры – реализация развернутых классов. Синтаксис структур. Сравнение структур и классов. Встроенные структуры. Перечисление – частный случай класса. Особенности перечислений. Примеры.

Ключевые слова: развернутый тип; ссылочный тип; структура; синтаксис структур; ограничения, накладываемые на структуры; встроенные структуры; перечисление; классы-перечисления; работа с объектами перечислений.

Развернутые и ссылочные типы

Рассмотрим объявление объекта класса T с инициализацией:

T x = new T();

Напомню, как выполняется этот оператор. В памяти создается объект типа T, основанного на классе T, и сущность x связывается с этим объектом. Сущность, не прошедшая инициализацию (явную или неявную), не связана ни с одним объектом, а потому не может использоваться в вычислениях – у нее нет полей, хранящих значения, она не может вызывать методы класса. Объектам нужна память, чтобы с ними можно было работать. Есть две классические стратегии выделения памяти и связывания объекта, создаваемого в памяти, и сущности, объявленной в тексте.

Определение 1. Класс T относится к развернутому типу, если память отводится сущности x; объект разворачивается на памяти, жестко связанной с сущностью.

Определение 2. Класс T относится к ссылочному типу, если память отводится объекту; сущность x является ссылкой на объект.

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

Развернутые и ссылочные типы порождают две различные семантики присваивания – развернутое присваивание и ссылочное присваивание. Рассмотрим присваивание:

y = x;

Когда сущность y и выражение x принадлежат развернутому типу, то при присваивании изменяется объект. Значения полей объекта, связанного с сущностью y, изменяются, получая значения полей объекта, связанного с x. Когда сущность y и выражение x принадлежат ссылочному типу, то изменяется ссылка, но не объект. Ссылка y получает значение ссылки x и обе они после присваивания указывают на один и тот же объект.

Язык программирования должен позволять программисту в момент определения класса указать, к развернутому или ссылочному типу относится класс. К сожалению, язык C# не позволяет этого сделать напрямую – в языке C# у класса нет модификатора, позволяющего задать развернутый или ссылочный тип. Какие же средства языка позволяют частично решить эту важную задачу? В лекции 3, где рассматривалась система типов языка C#, отмечалось, что все типы языка делятся на ссылочные и значимые типы. Термин «значимый» является синонимом термина «развернутый». Беда только в том, что деление на значимые и ссылочные типы предопределено языком и не управляется программистом. Напомню, к значимым типам относятся все встроенные арифметические типы, булев тип, структуры; к ссылочным типам – массивы, строки, классы. Так можно ли в C# спроектировать свой собственный класс так, чтобы он относился к значимым типам? Ответ на это вопрос положительный, хотя и с рядом оговорок. Для того чтобы класс отнести к значимым типам, его нужно реализовать как структуру.

Классы и структуры

Структура – это частный случай класса. Исторически структуры используются в языках программирования раньше классов. В языках PL/1, C, Pascal они представляли собой только совокупность данных (полей класса), но не включали ни методов, ни событий. В языке С++ возможности структур были существенно расширены и они стали настоящими классами, хотя и c некоторыми ограничениями. В языке C# – наследнике С++ сохранен именно такой подход к структурам.

Чем следует руководствоваться, делая выбор между структурой и классом? Полагаю, можно пользоваться следующими правилами:

Если необходимо отнести класс к развернутому типу, делайте его структурой.

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

В остальных случаях проектируйте настоящие классы.

Поскольку на структуры накладываются дополнительные ограничения, то может возникнуть необходимость в компромиссе – согласиться с ограничениями и использовать структуру, либо пожертвовать развернутостью и эффективностью и работать с настоящим классом. Стоит отметить, что когда говорится, что все встроенные типы – int и другие – представляют собой классы, то на самом деле речь идет о классах, реализованных в виде структур.

Структуры

Рассмотрим теперь более подробно вопросы описания структур, их синтаксиса, семантики и тех особенностей, что отличают их от классов.

Синтаксис структур

Синтаксис объявления структуры аналогичен синтаксису объявления класса:

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

{тело_структуры}

Какие изменения произошли в синтаксисе в сравнении с синтаксисом класса, описанным в лекции 16? Их немного. Перечислим их:

Ключевое слово class изменено на слово struct.

Список родителей, который для классов наряду с именами интерфейсов мог включать имя родительского класса, заменен списком интерфейсов. Для структур не может быть задан родитель (класс или структура). Заметьте, структура может наследовать интерфейсы.

Для структур не применимы модификаторы abstract и sealed. Причиной является отсутствие механизма наследования.

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

Аналогично классу структура может иметь статические и не статические поля и методы, может иметь несколько конструкторов, в том числе статические и закрытые конструкторы. Для структур можно создавать собственные константы, используя поля с атрибутом readonly и статический конструктор. Структуры похожи на классы по своему описанию и ведут себя сходным образом, хотя и имеют существенные различия в семантике присваивания.

Перечислим ограничения, накладываемые на структуры:

Самое серьезное ограничение связано с ограничением наследования. У структуры не может быть наследников. У структуры не может быть задан родительский класс или родительская структура. Конечно, всякая структура, как и любой класс в C#, является наследником класса object, наследуя все свойства и методы этого класса. Структура может быть наследником одного или нескольких интерфейсов, реализуя методы этих интерфейсов.

Второе серьезное ограничение связано с процессом создания объектов. Пусть T – структура и дано объявление без инициализации – T x; Это объявление корректно, в результате будет создан объект без явного вызова операции new. Сущности x будет отведена память и на этой памяти развернут объект. Но поля объекта не будут инициализированы и, следовательно, не будут доступны для использования в вычислениях. Об этих особенностях подробно говорилось при рассмотрении значимых типов. В этом отношении все, что верно для типа int, верно и для всех структур.

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

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

В конструкторе нельзя вызывать методы класса. Поля структуры должны быть проинициализированы до вызова методов.

Класс Rational или структура Rational

Вернемся к классу Rational, спроектированному в предыдущей лекции. Очевидно, что этот класс вполне разумно представить в виде структуры. Наследование ему не нужно. Семантика присваивания развернутого типа больше подходит для рациональных чисел, чем ссылочная семантика, ведь рациональные числа – это еще один подкласс арифметического класса. В общем класс Rational – прямой кандидат в структуры. Зададимся вопросом, насколько просто объявление класса превратить в объявление структуры? Достаточно ли заменить слово class словом struct? В данном случае одним словом не обойтись. Есть одно мешающее ограничение на структуры. В конструкторе класса Rational вызывается метод nod, а вызов методов в конструкторе запрещен. Нетрудно обойти это ограничение, изменив конструктор, явно задав вычисление общего делителя в его теле. Приведу текст этого конструктора:

public struct Rational

{

public Rational(int a, int b)

{

if(b==0) {m=0; n=1;}

else

{

//приведение знака

if(b<0) {b=-b; a=-a;}

//приведение к несократимой дроби

int p = 1, m1=a, n1 =b;

m1=Math.Abs(m1); n1 =Math.Abs(n1);

if(n1>m1){p=m1; m1=n1; n1=p;}

do

{

p = m1%n1; m1=n1; n1=p;

}while (n1!=0);

p=m1;

m=a/p; n=b/p;

}

}// Конструктор

//поля и методы класса

}

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

public void TwoSemantics()

{

Rational r1 = new Rational(1,3), r2 = new Rational(3,5);

Rational r3, r4;

r3 = r1+r2; r4 = r3;

if (r3 >1) r3 = r1+r3 + Rational.One; else r3 = r2+r3 - Rational.One;

r3.PrintRational("r3"); r4.PrintRational("r4");

}

В этом примере используются константы, работает статический конструктор, закрытый конструктор, перегруженные операции сравнения, арифметические выражения над рациональными числами. В результате вычислений r3 получит значение 8/15, r4– 14/15. Заметьте, аналогичный пример для класса Rational даст те же результаты. Для класса Rational и структуры Rational нельзя обнаружить разницу между ссылочным и развернутым присваиванием. Это связано с особенностью построения класса Rational – он по построению относится к неизменяемым (immutable) классам, аналогично классу string. Операции этого класса не изменяют поля объекта, а каждый раз создают новый объект. В этом случае можно считать, что объекты класса обладают присваиванием развернутого типа.

Встроенные структуры

Как уже говорилось, все значимые типы языка реализованы структурами. В библиотеке FCL имеются и другие встроенные структуры. Рассмотрим в качестве примера структуры: Point, PointF, Size, SizeF, Rectangle, находящиеся в пространстве имен System.Drawing и активно используемые при работе с графическими объектами. Первые четыре структуры имеют два открытых поля X и Y (Height и Width), задающие для точек – структур Point и PointF – координаты, целочисленные или в форме с плавающей точкой. Для размеров – структур Size и SizeF – высоту и ширину, заданные целочисленными значениями или в форме с плавающей точкой. Структуры Point и Size позволяют задать прямоугольную область – структуру Rectangle. Конструктору прямоугольника можно передать в качестве аргументов две структуры –точку, задающую координаты левого верхнего угла прямоугольника, и размер – высоту и ширину прямоугольника.

Между четырьмя структурами определены взаимные преобразования: точки можно преобразовать в размеры и наоборот, сложение и вычитание определено над размерами, точками и размерами, но не над точками, плавающий тип разными способами можно привести к целому. Ряд операций над этими структурами продемонстрирован в следующем примере:

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 ("cpt1.X =cpt1.X +10: " + cpt1);

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

}

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

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

Действия над объектами Point и CPoint выполняются аналогичные, а результаты получаются разные: в конце вычислений pt1 и pt2 различны, а 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, а woman – 2.

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

public void TestEnum()

{

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

MyColors color1= 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)1;

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, или с отложенной инициализацией, как color2. При объявлении без явной инициализации объект получает значение первой константы перечисления, так что color2 в момент объявления получает значение black.

Объекту можно присвоить значение, заданное константой перечисления, уточненной именем перечисления, как для color1 и color2. Можно также задать значение базового типа, приведенное к типу перечисления, как для color3.

Нельзя сравнивать объекты разных перечислений, например color1 и color2, но можно сравнивать строки, возвращаемые методом ToString, например color1.ToSting() и color2.Tostring().

Существуют явные взаимно обратные преобразования констант базового типа и констант перечисления.

Метод ToString, наследованный от класса Object, возвращает строку, задающую константу перечисления.

Персоны и профессии

Рассмотрим еще один пример работы с перечислениями, приближенный к реальности. Добавим в класс Person, рассмотренный в предыдущей лекции 16, поле, определяющее профессию персоны. Вполне разумно иметь перечисление, например Profession, задающее список возможных профессий. Сделаем это поле, как обычно закрытым, а доступ к нему обеспечим соответствующим свойством:

Profession prof;

public Profession Prof

{

get { return (prof);}

set {prof = value;}

}

Добавим еще в класс Person метод Analysis, анализирующий профессию, организуя традиционный разбор случаев и принимая решение на каждой ветви, в данном пример, выводя соответствующий текст:

public void Analysis()

{

switch (prof)

{

case Profession.businessman:

Console.WriteLine ("профессия: бизнесмен");

break;

case Profession.teacher:

Console.WriteLine ("профессия: учитель");

break;

case Profession.engineer:

Console.WriteLine ("профессия: инженер");

break;

default:

Console.WriteLine ("профессия: неизвестна");

break;

}

}

Приведу простой тестирующий пример работы с объектом Person и его профессией:

public void TestProfession()

{

Person pers1 = new Person ("Петров");

pers1.Prof = Profession.teacher;

pers1.Analysis();

}

Результаты работы с объектами перечислений, полученные при вызове тестов TestEnum и TestProfession показаны на рис. 17.3.

Рис. 17.3. Результаты работы с перечислениями

Вариант 1

46. Какие утверждения справедливы для развернутых и ссылочных типов?

q структуры относятся к развернутым типам;

q классы относятся к ссылочным типам;

q модификатор expand позволяет отнести класс к развернутому типу;

q объектам развернутого типа память отводится в куче;

q память для ссылок отводится в стеке.

47. Отметьте истинные высказывания:

q у перечислений нет конструкторов;




Поделиться с друзьями:


Дата добавления: 2014-12-25; Просмотров: 523; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.183 сек.