Эндрю Троелсен - ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89)
.ver 2:0:0:0
}
.assembly CSharpCalculator
{
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module CSharpCalculator.exe
.imagebase 0x00400000
.subsystem 0x00000003
.file alignment 512
.corflags 0x00000001
По сути, этот манифест содержит указания на внешние компоновочные блоки, необходимые для CSharpCalculator.exe (для этого используется директива.assembly extern), а также различные характеристики самого компоновочного блока (номер версии, имя модуля и т.д.).
Общая система типов
Компоновочный блок может содержать любое число четко определенных "типов". В мире .NET "тип" – это просто общий термин, используемый для обозначения любого элемента из множества {класс, структура, интерфейс, перечень, делегат}. При построении решений с помощью любого языка .NET вы, скорее всего, будете взаимодействовать с каждым из этих типов. Например, компоновочный блок может определять один класс, в котором реализовано ряд интерфейсов. И, возможно, один из методов интерфейса будет принимать перечень в качестве входного параметра, а возвращать некоторую структуру.
Напомним, что CTS (общая система типов) – это формальное описание того, как должны определяться типы, подходящие для использования в среде CLR. Обычно внутренние механизмы CTS важны только тем, кто создает средства разработки и/или строит компиляторы для платформы .NET. Но для любого программиста .NET важно знать, как работать с пятью типами, определяемыми спецификациями CTS для выбранного разработчиком языка программирования. Ниже предлагается краткий обзор соответствующих вопросов.
Тип класса
Любой язык, совместимый с .NET, поддерживает, как минимум, тип класса, который является "краеугольным камнем" объектно-ориентированного программирования (ООП). Класс может состоять из любого числа членов (таких, как свойства, методы и события) и элементов данных (таких, как поля). В C# классы объявляются с помощью ключевого слова class.
// Тип класса C#.
public class Calc {
public int Add(int x, int y) {return x + y;}
}
Процесс построения типов класса CTS в C# будет рассматриваться в главе 4, но ряд общих характеристик типов класса приводится в табл. 1.2.
Таблица 1.2. Характеристики классов CTS
Характеристика класса Описание Изолированность Изолированные классы не могут быть базой для создания других классов, т.е. не позволяют наследование Наличие интерфейсов Интерфейс - это набор абстрактных членов, обеспечивающих взаимодействие между объектом и пользователем этого объекта. Спецификации CTS не ограничивают число интерфейсов, реализуемых в рамках класса Абстрактность или конкретность Абстрактные классы не позволяют непосредственное сознание их экземпляров – они предназначены для определения общих элементов поведения производных типов. Конкретные классы могут быть созданы непосредственно Видимость Каждый класс должен иметь атрибут видимости (visibility). По сути, этот атрибут указывает, доступен данный класс для использования внешними компоновочными блоками или он доступен для использования только внутри определяющего этот класс компоновочного блока (как, например, приватный класс справки)Тип структуры
Понятие структуры в CTS также формализовано. Если вы знаете C, вам будет приятно узнать, что эти пользовательские типы "выжили" и в мире .NET (хотя внутренне они ведут себя немного по-иному). Упрощенно говоря, структура - это "облегченный" тип класса с семантикой на базе значений. Более подробная информация о структурах предлагается в главе 3. Обычно структуры лучше всего подходят для моделирования геометрических и математических данных, и в C# для создания структур используется ключевое слово struct.
// Тип структуры C#.
struct Point {
// Структуры могут содержать поля.
public int xPos, yPos;
// Структуры могут содержать параметризованные конструкторы.
public Point (int x, int у) {xPos = x; yPos = y;}
// Структуры могут определять методы.
public void Display() {
Console.WriteLine("({0}, {1})", xPos, yPos);
}
}
Тип интерфейса
Интерфейс - это именованная коллекция определений абстрактных членов, которая может поддерживаться (т.е. реализоваться) данным классом или структурой. В отличие от модели COM, интерфейсы .NET не являются производными одного общего базового интерфейса, такого как IUnknown. В C# типы интерфейса определяются с помощью ключевого слова interface, например:
// Тип интерфейса C#.
public interface IDraw {
void Draw ();
}
Сами по себе интерфейсы не очень полезны. Однако, когда класс или структура реализуют данный интерфейс своим собственным уникальным образом, вы можете запросить доступ к соответствующим функциональным возможностям, используя ссылку на интерфейс в полиморфной форме. Программирование на базе интерфейсов будет рассматриваться в главе 7.
Тип перечня
Перечень - это удобная программная конструкция, в которой группируются пары "имя-значение". Предположим, вы создаете видеоигру, в которой игроку позволяется выбрать персонажа в одной из трех категорий: Wizard (маг), Fighter (воин) или Thief (мошенник). Вместо того чтобы использовать и отслеживать числовые значения, соответствующие каждой из возможностей, вы можете построить перечень, используя для этого ключевое слово enum.
// Тип перечня C#.
public enum CharacterType {
Wizard = 100,
Fighter = 200,
Thief = 300
}
По умолчанию для каждого элемента выделяется блок памяти, соответствующий 32-битовому целому, но при необходимости это значение можно изменить (например, в случае программирования для устройств с малыми объемами памяти, таких как КПК). Спецификации CTS предполагают, что типы перечня должны "получаться" из общего базового класса, System.Enum. Из главы 3 вы узнаете, что этот базовый класс определяет ряд весьма полезных членов, которые позволяют программно извлекать, обрабатывать и преобразовывать соответствующие пары "имя-значение".
Тип делегата
Делегат - это .NET-эквивалент обеспечивающих типовую безопасность указателей функций C. Главное отличие заключается в том, что делегат .NET- это класс, получаемый путем наследования System.MulticastDelegate, а не просто указатель на конкретный адрес в памяти. В C# делегаты объявляются с помощью ключевого слова delegate.
// Этот тип делегата C# может 'указывать' на любой метод, возвращающий
// целое значение и получающий на вход два целых значения.
public delegate int BinaryOp(int x, int y);
Делегаты полезны, когда требуется обеспечить элементу возможность передачи вызова другому элементу, что создает основу для архитектуры обработки событий .NET. В главах 8 и 14 будет показано, что делегаты имеют внутреннюю поддержку методов многоадресного (предназначенного для множества получателей) и асинхронного вызова.
Члены типов
Теперь после рассмотрения всех типов, имеющих формальное определение в CTS, вы должны осознать, что большинство типов может иметь любое число членов. Формально член типа - это любой элемент множества {конструктор, деструктор (finalizer), статический конструктор, вложенный тип, операция, метод, свойство, индексатор, поле, поле только для чтения, константа, событие}.
Спецификации CTS определяют различные "характеристики", которые могут связываться с данным членом. Например, каждый член имеет признак, характеризующий его доступность (открытый, частный, защищенный и т.д.). Некоторые члены могут объявляться как абстрактные, чтобы навязать полиморфное поведение производным типам, или виртуальные, чтобы определить фиксированную (но допускающую замену) реализацию. Большинство членов может обозначаться как статические ("привязанные" к уровню класса) или как члены экземпляра ("привязанные" к уровню объекта). Конструкция членов типа будет подробно обсуждаться в следующих главах.