Тверской государственный университет
Опубликован: 22.11.2005 | Доступ: свободный | Студентов: 30405 / 1848 | Оценка: 4.31 / 3.69 | Длительность: 28:26:00
ISBN: 978-5-9556-0050-5
Лекция 17:

Структуры и перечисления

< Лекция 16 || Лекция 17: 1234 || Лекция 18 >
Еще раз о двух семантиках присваивания

В заключение разговора о ссылочных и развернутых типах построим класс 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.ToString() и color2.ToString() ;
  • существуют явные взаимно обратные преобразования констант базового типа и констант перечисления ;
  • Метод ToString, наследованный от класса Object, возвращает строку, задающую константу перечисления.
< Лекция 16 || Лекция 17: 1234 || Лекция 18 >
Александр Галабудник
Александр Галабудник

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

Александра Гусева
Александра Гусева