Кроме примитивных типов данных в C# есть такой тип как enum или перечисление. Перечисления представляют набор логически связанных констант. Объявление перечисления происходит с помощью оператора enum. Далее идет название перечисления, после которого указывается тип перечисления - он обязательно должен представлять целочисленный тип (byte, int, short, long). Если тип явным образом не указан, то умолчанию используется тип int. Затем идет список элементов перечисления через запятую:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | enum Days { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday } enum Time: byte { Morning, Afternoon, Evening, Night } |
В этих примерах каждому элементу перечисления присваивается целочисленное значение, причем первый элемент будет иметь значение 0, второй - 1 и так далее. Мы можем также явным образом указать значения элементов, либо указав значение первого элемента:
1 2 3 4 5 6 7 | enum Operation { Add = 1, // каждый следующий элемент по умолчанию увеличивается на единицу Subtract, // этот элемент равен 2 Multiply, // равен 3 Divide // равен 4 } |
Но можно и для всех элементов явным образом указать значения:
|
|
1 2 3 4 5 6 7 | enum Operation { Add = 2, Subtract = 4, Multiply = 8, Divide = 16 } |
Каждое перечисление фактически определяет новый тип данных. Затем в программе мы можем определить переменную этого типа и использовать ее:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class Program { enum Operation { Add = 1, Subtract, Multiply, Divide } static void Main(string[] args) { Operation op; op = Operation.Add; Console.WriteLine(op); // Add Console.ReadLine(); } } |
В программе мы можем присвоить значение этой переменной. При этом в качестве ее значения должна выступать одна из констант, определенных в данном перечислении. То есть несмотря на то, что каждая константа сопоставляется с определенным числом, мы не можем присвоить ей числовое значение, например, Operation op = 1;. И также если мы будем выводить на консоль значение этой переменной, то мы получим им константы, а не числовое значение. Если же необходимо получить числовое значение, то следует выполнить приведение к числовому типу:
1 2 3 | Operation op; op = Operation.Multiply; Console.WriteLine((int)op); // 3 |
Также стоит отметить, что перечисление необязательно определять внутри класса, можно и вне класса, но в пределах пространства имен:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | enum Operation { Add = 1, Subtract, Multiply, Divide } class Program { static void Main(string[] args) { Operation op; op = Operation.Add; Console.WriteLine(op); // Add Console.ReadLine(); } } |
Зачастую переменная перечисления выступает в качестве хранилища состояния, в зависимости от которого производятся некоторые действия. Так, рассмотрим применение перечисления на более реальном примере:
|
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | class Program { enum Operation { Add = 1, Subtract, Multiply, Divide } static void MathOp(double x, double y, Operation op) { double result = 0.0; switch (op) { case Operation.Add: result = x + y; break; case Operation.Subtract: result = x - y; break; case Operation.Multiply: result = x * y; break; case Operation.Divide: result = x / y; break; } Console.WriteLine("Результат операции равен {0}", result); } static void Main(string[] args) { // Тип операции задаем с помощью константы Operation.Add, которая равна 1 MathOp(10, 5, Operation.Add); // Тип операции задаем с помощью константы Operation.Multiply, которая равна 3 MathOp(11, 5, Operation.Multiply); Console.ReadLine(); } } |
Здесь у нас имеется перечисление Operation, которое представляет арифметические операции. Также у нас определен метод MathOp, который в качестве параметров принимает два числа и тип операции. В основном методе Main мы два раза вызываем процедуру MathOp, передав в нее два числа и тип операции.
Лекция 17. Структуры
Кроме базовых элементарных типов данных и перечислений в C# имеется и составной тип данных, который называется структурой. Структуры могут содержать в себе обычные переменные и методы.
Для примера создадим структуру Book, в которой будут храниться переменные для названия, автора и года издания книги. Кроме того, структура будет содержать метод для вывода информации о книге на консоль:
1 2 3 4 5 6 7 8 9 10 11 | struct Book { public string name; public string author; public int year; public void Info() { Console.WriteLine("Книга '{0}' (автор {1}) была издана в {2} году", name, author, year); } } |
Чтобы можно было использовать переменные и методы структуры из любого места программы мы ставим перед переменными и методом модификатор доступа public
Используем структуру на практике:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | using System; namespace Structures { class Program { static void Main(string[] args) { Book book; book.name = "Война и мир"; book.author = "Л. Н. Толстой"; book.year = 1869; //Выведем информацию о книге book на экран book.Info(); Console.ReadLine(); } } struct Book { public string name; public string author; public int year; public void Info() { Console.WriteLine("Книга '{0}' (автор {1}) была издана в {2} году", name, author, year); } } } |
Структуру можно задать как внутри пространства имен (как в данном случае), так и внутри класса, но не внутри метода.
По сути структура Book представляет новый тип данных. Мы также можем использовать массив структур:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Book[] books=new Book[3]; books[0].name = "Война и мир"; books[0].author = "Л. Н. Толстой"; books[0].year = 1869; books[1].name = "Преступление и наказание"; books[1].author = "Ф. М. Достоевский"; books[1].year = 1866; books[2].name = "Отцы и дети"; books[2].author = "И. С. Тургенев"; books[2].year = 1862; foreach (Book b in books) { b.Info(); } |