Система типов
Перечисления
Перечисление объявляется с помощью ключевого слова enum, идентифицируется по имени и представляет собой непустой список неизменяемых именованных значений интегрального типа. Первое значение в перечислении по умолчанию инициализируется нулем. Каждое последующее значение отличается от предыдущего по крайней мере на единицу, если объявление значения не содержит явного дополнительного присвоения нового значения. Пример объявления перечисления приводится ниже:
enum Colors { Red = 1, Green = 2, Blue = 4, Yellow = 8 };
Обращение к элементу перечисления осуществляется посредством сложного выражения, состоящего из имени класса перечисления, операции доступа к элементу перечисления ' .', имени элемента перечисления:
int xVal = (int)Colors.Red; //Переменная xVal инициализируется значением перечисления.
Перечисление является классом, а это означает, что в распоряжении программиста оказываются методы сравнения значений перечисления, методы преобразования значений перечисления в строковое представление, методы перевода строкового представления значения в перечисление, а также (судя по документации) средства для создания объектов —представителей класса перечисления.
Далее приводится список членов класса перечисления.
CompareTo | Сравнивает этот экземпляр с заданным объектом и возвращает сведения об их относительных значениях |
Equals | Переопределен. Возвращает значение, показывающее, равен ли данный экземпляр заданному объекту |
Format | Статический. Преобразует указанное значение заданного перечисляемого типа в эквивалентное строчное представление в соответствии с заданным форматом |
GetHashCode | Переопределен. Возвращает хэш-код для этого экземпляра |
GetName | Статический. Выводит имя константы в указанном перечислении, имеющем заданное значение |
GetNames | Статический. Выводит массив имен констант в указанном перечислении |
GetType (унаследовано от Object ) | Возвращает Type текущего экземпляра |
GetTypeCodeType | Возвращает базовый тип TypeCode для этого экземпляра |
GetUnderlying | Статический. Возвращает базовый тип указанного перечисления |
GetValues | Статический. Выводит массив значений констант в указанном перечислении |
IsDefined | Статический. Возвращает признак наличия константы с указанным значением в заданном перечислении |
Parse | Статический. Перегружен. Преобразует строковое представление имени или числового значения одной или нескольких перечисляемых констант в эквивалентный перечисляемый объект |
ToObject | Статический. Перегружен. Возвращает экземпляр указанного типа перечисления, равный заданному значению |
ToString | Перегружен. Переопределен. Преобразует значение этого экземпляра в эквивалентное ему строковое представление |
Защищенные конструкторы
Защищенные методы
Finalize (унаследовано от Object ) | Переопределен. Позволяет объекту Object попытаться освободить ресурсы и выполнить другие завершающие операции, перед тем как объект Object будет уничтожен в процессе сборки мусора. В языках C# и C++ для функций финализации используется синтаксис деструктора |
MemberwiseClone (унаследовано от Object) | Создает неполную копию текущего Object |
Объявление переменных. Область видимости и время жизни
Любая используемая в программе сущность вводится объявлением.
Объявлению подлежат:
- классы и структуры. Класс (структура) может содержать вложенные объявления других классов и структур;
- перечисления;
- объекты – переменные и константы, представляющие классы и структуры. Корректное объявление объекта предполагает, что информация, содержащая характеристики объявляемого объекта, доступна транслятору;
- элементы перечислений – объекты, представляющие перечисления;
- конструкторы классов и методы (функции) – члены классов (в том числе и специальные).
Объявляемой сущности присваивается имя. Обращение к ранее объявленным сущностям в программе обеспечивается различными вариантами имен. Имена в программе повсюду, и главная проблема заключается в том, чтобы не допустить неоднозначности при обращении из разных мест программы к классам, членам классов, перечислениям, переменным и константам.
Конфликта имен (проблемы с обращением к одноименным объектам) позволяет избежать принятая в языке дисциплина именования. В каждом языке программирования она своя.
Избежать конфликта имен в C# позволяет такая синтаксическая конструкция, как блок операторов. Блок – это множество предложений (возможно пустое), заключенное в фигурные скобки.
Различается несколько категорий блоков:
- Тело класса (структуры). Место объявления членов класса.
- Тело метода. Место расположения операторов метода.
- Блок в теле метода.
Переменные можно объявлять в любом месте блока. Точка объявления переменной в буквальном смысле соответствует месту ее создания. Обращение к объявляемой сущности (переменной или константе) "выше" точки ее объявления лишено смысла.
Новый блок – новая область видимости. Объекты, объявляемые во внутренних блоках, не видны во внешних блоках. Объекты, объявленные в методе и во внешних блоках, видны и во внутренних блоках. Одноименные объекты во вложенных областях конфликтуют.
Объекты, объявляемые в блоках одного уровня вложенности в методе, не видны друг для друга. Конфликта имен не происходит.
В теле класса не допускается объявления одноименных данных-членов. Нарушение этого правила приводит к неоднозначности.
В теле класса не допускается объявления одноименных функций — членов (методов класса) с пустыми списками параметров. Также не допускаются объявления одноименных функций — членов (методов класса) со списками параметров, у которых совпадают типы параметров.
В списках параметров имена параметров не важны. Важно, что выражение вызова метода в этом случае будет неоднозначным.
Имена данных — членов класса не конфликтуют с одноименными переменными, объявляемыми в теле методов, поскольку в теле метода обращение к членам класса обеспечивается выражениями с операцией доступа, и никакого конфликта в принципе быть не может.
Ниже приводится простой программный код, отражающий особенности принятой в C# концепции областей видимости.
using System; class Class1 { static int s; static void Main(string[] args) { {int s;} {int s;} { Class1.s = 100; // Классифицированное имя! int s; { //int s; } } System.Int32 z = new int(); char a = (char)41; char b = 'X'; Console.WriteLine("{0} {1}",a,b); } //void QQQ(int q0) //{ //Class1.s = 10; //int s; //} //void QQQ(int q1) //{ //Class1.s = 10; //int s; //} int QQQ(int q2) { Class1.s = 10; int s; return 0; } int QQQ(int q2, int q3) { //s = 100; Class1.s = 10; int s; return 0; } }Листинг 2.2.