Шаг 190.
Язык программирования C#. Начала.
Перечисления и структуры. Знакомство с перечислениями (окончание)

    На этом шаге мы рассмотрим пример использования перечисления.

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace pr190_1
{
    // Объявление перечисления:
    enum Animals { Cat, Dog, Fox, Wolf, Bear };
    // Объявление перечисления с инициализацией констант: 
    enum Coins {One=1, Two, Five=5, Ten=10, Fifty=50};

    // Класс с главным методом: 
    class Program
    {
        // Главный метод:
        static void Main()
        {
            Console.WriteLine("B мире животных");
            // Переменная типа перечисления:
            Animals animal = Animals.Cat;
            Console.WriteLine("animal: {0,-5} или {1}", animal, (int)animal);
            // Новое значение переменной: 
            animal = Animals.Dog;
            Console.WriteLine("animal: {0,-5} или {1}", animal, (int)animal);
            // Преобразование целого числа в значение 
            // типа перечисления: 
            animal = (Animals)2;
            Console.WriteLine("animal: {0,-5} или {1}", animal, (int)animal);
            // Сумма переменной и целого числа: 
            animal = animal + 1;
            Console.WriteLine("animal: {0,-5} или {1}", animal, (int)animal);
            // Применение операции инкремента: 
            animal++;
            Console.WriteLine("animal: {0,-5} или {1}", animal, (int)animal); 
            Console.WriteLine("B мире финансов");
            // Переменная типа перечисления:
            Coins coin;
            // Объект с константами из перечисления:
            Array names = Enum.GetValues(typeof(Coins));
            // Перебор констант:
            for (int k = 0; k < names.Length; k++)
            {
                // Значение переменной: 
                coin = (Coins)names.GetValue(k);
                Console.WriteLine("coin: {0,-5} или {1}", coin, (int)coin);
            }
            // Задержка:
            Console.ReadLine();
        }
    }
}
Архив проекта можно взять здесь.

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


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

    В этой программе мы объявляем два перечисления: перечисление Animals объявляется командой

  enum Animals { Cat, Dog, Fox, Wolf, Bear };        , 
а перечисление Coins объявляется командой
  enum Coins {One=1, Two, Five=5, Ten=10, Fifty=50};               .

    В главном методе программы командой

  Animals animal = Animals.Cat;
объявляется и инициализируется переменная animal типа Animals. При отображении значения переменной animal в консольном окне отображается символьное название константы, которая присвоена в качестве значения переменной. Чтобы узнать целочисленное значение константы, используем инструкцию (int)animal, в которой выполняется явное приведение к целочисленному типу.


Инструкция {0,-5} в текстовой строке в аргументе метода WriteLine() означает, что для отображения соответствующего значения выделяется 5 позиций и выравнивание выполняется по левому (из-за знака минус) краю.

    Новое значение переменной animal присваивается командами

  animal = Animals.Dog;
(значением присваивается константа из перечисления),
  animal = (Animals)2;
(выполняется явное приведение целочисленного значения к типу Animals),
  animal = animal + 1;
(увеличение текущего значения переменной на единицу), а также
  animal++;
(применение операции инкремента). При выполнении последних операций мы приняли в расчет, что числовые значения констант отличаются друг от друга на единицу. Но в общем случае это не всегда так: например, перечисление Coins. Для работы с этим перечислением мы командой
  Coins coin;
объявляем переменную coin. Но проблема здесь в том, что константы из перечисления Coins имеют "уникальные" целочисленные значения. Лишь для констант One и Two значения отличаются на единицу, значения всех прочих констант заданы индивидуально. Поэтому перебор ряда натуральных чисел с помощью цикла не очень подходит. Мы поступаем немного хитрее. Сначала с помощью команды
   Array names = Enum.GetValues(typeof(Coins));
создаем объект names класса Array, содержащий набор значений констант из перечисления Coins. Для этого из класса Enum вызывается статический метод GetValues(). Результатом метод возвращает ссылку на объект класса Array. Этот объект по свойствам напоминает массив и содержит, как отмечалось, значения, формирующие тип Coins. Аргументом методу GetValues() передается объект класса Type, который содержит информацию о перечислении Coins. Этот объект можно получить с помощью инструкции typeof(Coins). Для перебора значений, формирующих тип перечисления Coins, мы запускаем цикл, в котором используем индексную переменную k. Количество элементов в объекте names вычисляется выражением names.Length, как для массива. Для считывания очередного значения, содержащегося в объекте names, используем метод GetValue(). Аргументом методу передается индекс считываемого элемента. Но поскольку значением выражения names.GetValue(k) является объектная ссылка класса object, то мы используем процедуру явного приведения типа. В итоге получается команда
  coin = (Coins)names.GetValue(k);                   , 
которой значение присваивается переменной coins. В консольном окне отображается значение этой переменной и его целочисленный "эквивалент".


Есть несколько обстоятельств, которые нужно иметь в виду при работе с перечислениями. Во-первых, как мы знаем, константы, формирующие тип перечисления, являются целочисленными. Предполагается, что значением переменной типа перечисления может быть одна из таких констант. Но дело в том, что технических ограничений на значения для переменной типа перечисления нет. Это означает, что переменная может получить целочисленное значение, которое не совпадает со значением ни одной из констант из перечисления. Например, если в рассмотренном выше примере выполнить команду
  animal = (Animals)5;                 , 
то ошибки не будет, хотя в списке констант перечисления Animals константы со значением 5 нет. Это же замечание относится к операциям вида
  animal++; 
или
  animal = animal + 1; 
если окажется, что новое вычисленное значение не представлено константой в списке перечисления, то оно все рано будет записано в переменную.

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


    На следующем шаге мы начнем знакомиться со структурами.




Предыдущий шаг Содержание Следующий шаг