Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Podbelsky_V_V_C_Bazovy_kurs.pdf
Скачиваний:
69
Добавлен:
02.06.2015
Размер:
1.73 Mб
Скачать

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

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

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

е.с одним элементом данных) несколько переменных с типом (или типами) значений. (Вопрос о том, что для переменных с типами значений память выделяется в стеке, мы уже обсуждали.) Итак, и перечисления, и структуры дают возможность объявлять пользовательские типы значений. Начнем с перечислений.

Перечисление – особый тип, определяющий набор именованных целочисленных констант. Формат объявления перечисления:

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

Имя_перечисления – выбранный программистом идентификатор, который становится именем нового типа.

Список_перечисления – список неповторяющихся имен констант, для каждой из которых указано или задано по умолчанию инициализирующее выражение (значения инициализирующих выражений могут совпадать).

enum – служебное слово.

Конструкция “:базовый_тип” может быть опущена, и тогда константы списка имеют тип int. В качестве базового типа явно можно использовать любой целый тип (int, long, …), кроме char.

Вкачестве модификаторов перечислений могут использоваться new, public, protected, internal, private.

Вкачестве примера введем перечисление – тип с именем НомерПланеты, объявляющее константы, значениями которых служат номера наиболее известных малых планет.

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

293

 

 

enum НомерПланеты : uint

{ Церера = 1, Паллада = 2, Юнона = 3, Веста = 4, Эрос = 433, Гидальго = 944, Ганимед = 1036, Амур =1221, Икар = 1566

}

Номера планет (по астрономическому каталогу) – это целые положительные числа, поэтому в качестве базового типа выбран тип констант uint. В списке перечисления НомерПланеты имена констант – это названия планет, и каждой константе приписано конкретное значение – номер планеты по каталогу.

Если для констант перечисления не заданы инициализирующие выражения, то первой константе присваивается нулевое значение, а каждая следующая получает значение на 1 больше. Если в списке перечисления отсутствует инициализация для не первой константы, то она получает значение на 1 больше, чем предыдущая. Операндами инициализирующего выражения могут быть только константы. Значение инициализирующего выражения должно принадлежать области допустимых значений базового типа перечисления.

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

enum НомерПланеты : uint

{ Церера = 1, Паллада, Юнона=Веста–Церера, Веста=4, Эрос = 433, Гидальго = 944, Ганимед = 1036, Амур =1221,

Икар = 1566

}

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

имя_перечисления.имя_константы_из_списка

Как многократно повторялось, все типы языка C# являются производными от базового класса System.Object. Это относится и к перечислениям. Поэтому к ним применимы уже рассмот-​ ренные нами методы класса Object. Однако непосредственным (прямым) базовым классом для перечислений служит класс

294

Г л а в а 1 5

 

 

System.Еnum, который построен на базе класса Object. В классе System.Еnum методы класса Object переопределены с тем, чтобы максимально приблизиться к задачам, решаемым с помощью перечислений.

Например (программа 15_01.cs):

string str = НомерПланеты.Икар.ToString();

Значением str будет строка “Икар” (а вовсе не “1566”, что соответствовало бы значению константы).

Хотя константы перечисления имеют целочисленные значения, однако их типом служит то конкретное перечисление, которому они принадлежат. Если применить к константе перечисления метод GetType(), то строка–результат будет иметь вид:

"имя_класса+имя_перечисления"

Здесь указывается имя того класса, в котором определено перечисление. Обратите внимание, что разделяет или соединяет имена знак «+». Например, если перечисление НомерПланеты объявлено в классе Program (15_01.cs), то значением выражения

НомерПланеты.Веста.GetType()

будет строка

"Program+НомерПланеты".

При конкатенации со строкой квалифицированное имя

имя_перечисления.имя_константы_из_списка

трактуется как строка вида «имя_константы_из_списка». Например (программа 15_02.cs), значением выражения:

"имя планеты: "+НомерПланеты.Амур

будет строка

"имя планеты: Амур".

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

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

295

 

 

будет строка:

"Юнона имеет номер 3".

Вто же время при использовании констант перечисления

варифметических выражениях они воспринимаются как целочисленные значения. Например (программа 15_02.cs):

long res = НомерПланеты.Ганимед – НомерПланеты. Гидальго;

значением переменной res будет 92.

Так как enum вводит тип, то разрешено определять переменные этого типа. Такая переменная имеет право принимать значения именованных целочисленных констант, введенных соответствующим перечислением. В этом случае переменная приобретает свойства этих констант. Например, рассмотрим последовательность операторов (программа 15_03.cs):

НомерПланеты number = НомерПланеты.Амур; string str = number.ToString(); Console.WriteLine("str: " + str);

long res = number - НомерПланеты.Веста;

Значением str будет “Амур”, значением переменной res будет 1217.

К константам перечисления и переменным с типом перечисления применимы: операции сравнения (==, !=, <, >, <=, >=), бинарная арифметическая операция –, поразрядные операции (^, &, |, ~) и sizeof. К переменным с типом перечисления применимы унарные операции ++, --.

Обратите внимание, что к константам перечисления нельзя применять бинарные арифметические операции +, /, *, % и унарные операции – и +. Таким образом, нельзя выполнить суммирование или деление двух констант перечисления.

Поэтому для использования значений констант или переменных с типом перечисления в арифметических выражениях необходимо выполнить явное приведение их типов. Например, так:

НомерПланеты.Юнона+ " имеет номер "+(int)

number = (НомерПланеты)((int) НомерПланеты.Церера +

НомерПланеты.Юнона

(int) НомерПланеты.Юнона);

 

296

Г л а в а 1 5

 

 

После выполнения этого оператора переменная number примет значение константы перечисления со значением 4 и именем “Веста”.

Чтобы присвоить переменной с типом перечисления значение (даже того типа, который является для перечисления базовым), необходимо явное приведение типов. Например, так:

number = (НомерПланеты)944;

Переменная number примет значение константы Гидальго. Если переменной с типом перечисления присвоить значение,

которое отсутствует в списке именованных констант, то имя представляемой переменной константы совпадёт с её значением. Например:

number = (НомерПланеты)999;

Переменная number примет значение константы перечисления с именем “999” и значением 999.

Операции автоизменений (декремент -- и инкремент ++) позволяют так изменять значение переменной перечисления, что она принимает и значения, отсутствующие среди именованных констант перечисления. Принимая такие значения, переменная перечисления играет роль литерала – ее имя совпадает

спредставленным значением.

Вследующей программе введена переменная number перечисления НомерПланеты, значением которой в цикле становятся константы Церера, Паллада, Юнона, Веста. Затем переменная number принимает значения, отсутствующие в перечислении.

// 15_04.cs переменная перечисления using System;

class Program

{

enum НомерПланеты : uint

{

Церера = 1, Паллада = 2, Юнона = 3, Веста = 4, Эрос = 433, Гидальго = 944, Ганимед = 1036,

Амур = 1221, Икар = 1566

}

static void Main()

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

297

 

 

{

НомерПланеты number; Console.WriteLine("Номера планет: "); for (number = НомерПланеты.Церера;

number <= НомерПланеты.Веста + 2; number++)

Console.WriteLine(number + " = " + (int)number);

}

}

Результат выполнения программы:

Номера планет: Церера = 1 Паллада = 2 Юнона = 3 Веста = 4 5 = 5

6 = 6

Члены (константы) перечислений и переменные с типами перечислений можно использовать в качестве аргументов методов и в метках переключателей. В метке переключателя член перечисления применяется в качестве константного выражения. В следующей программе статический метод данныеОпланете() имеет параметр с типом перечисления НомерПланеты. Метод выводит в консольное окно некоторые сведения о планетах с конкретными номерами.

// 15_05.cs переменная перечисления в

переключателе using System; class Program

{

enum НомерПланеты : uint

{

Церера = 1, Паллада = 2, Юнона = 3, Веста = 4, Эрос = 433, Гидальго = 944, Ганимед = 1036,

Амур = 1221, Икар = 1566

}

static void данныеОпланете(НомерПланеты p)

{

switch (p)

298

Г л а в а 1 5

 

 

{

case НомерПланеты.Амур: Console.WriteLine("Номер: {0}, название: {1},

диаметр: {2}",

(int)p, p, 1.5); break;

case НомерПланеты.Веста: Console.WriteLine("Номер: {0}, название: {1},

диаметр: {2}",

(int)p, p, 380); break;

//Про остальные планеты из экономии ничего не пишем...

}

}

static void Main()

{

НомерПланеты number; number = НомерПланеты.Веста; данныеОпланете(number);

данныеОпланете(НомерПланеты.Амур);

}

}

Результат выполнения программы:

Номер: 4, название: Веста, диаметр: 380 Номер: 1221, название: Амур, диаметр: 1,5

В функции Main() определена переменная number с типом перечисления НомерПланеты. Ей присвоено значение константы перечисления Веста, и переменная служит аргументом при обращении к методу данныеОпланете(). При втором обращении к тому же методу аргумент – квалифицированное имя другой константы перечисления.

15.2. Базовый класс перечислений

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

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

299

 

 

public static Type GetUnderlyingType (Тип_Перечисления);

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

public static string GetName (Тип_Перечисления,

значение);

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

public static string Format (Тип_Перечисления, значение, формат);

второй параметр – переменная с типом перечисления либо значение константы. В зависимости от формата возвращается либо имя, либо значение константы. Если формат "G" или "g", то метод подобен GetName – возвращает имя константы. Если формат "X" или "x" – возвращается шестнадцатеричное представление значения константы. При формате "D" или "d" – возвращается десятичное представление.

public static Array GetValues (Тип_Перечисления);

метод возвращает массив значений всех констант перечисления. Константы независимо от их размещения в перечислении в массиве размещаются по возрастанию значений. Обратите внимание, что тип результата System.Array.

public static string [ ] GetNames (Тип_Перечисления);

метод возвращает массив имен констант перечисления в порядке возрастания значений констант.

public static bool IsDefined (Тип_Перечисления,

значение);

возвращает true, если в перечислении присутствует константа со значением, равным второму параметру.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]