static void Main(string[] args) {
…
Stack stringStack = new Stack();
stringStack.Push("Первый");
stringStack.Push("Второй");
stringStack.Push("Третий");
// Смотрим на первый элемент, удаляем его и смотрим снова.
Console.WriteLine("Первый элемент: {0}", stringStack.Peek());
Console.WriteLine("Удален {0}", stringStack.Pop());
Console.WriteLine("Первый элемент: {0}", stringStack.Peek());
Console.WriteLine("Удален {0}", stringStack.Pop());
Console.WriteLine("Первый элемент: {0}", stringStack.Peek());
Console.WriteLine("Удален {0}", stringStack.Pop());
try {
Console.WriteLine("Первый элемент: {0}", stringStack.Peek());
Console.WriteLine ("Удален {0}", stringStack.Pop());
} catch(Exception e) {Console.WriteLine("Ошибка: {0}", e.Message);}
}
Здесь строится стек, содержащий три строковых типа (названных в соответствии с порядком их вставки). "Заглядывая" в стек, вы видите элемент, находящийся на вершине стека, поэтому первый вызов Peek() выявляет третью строку. После серии вызовов Pop() и Peek() стек, в конечном счете, опустошается, и тогда дополнительный вызов Peek()/Pop() приводит к генерированию системного исключения.
Исходный код.Проект CollectionTypes размещен в подкаталоге, соответствующем главе 7.
Пространство имен System.Collections.Specialized
Кроме типов, определенных в пространстве имен System.Collections, библиотеки базовых классов .NET предлагают набор более специализированных типов, определенных в пространстве имен System.Collections.Specialized. Например, типы StringDictionary и ListDictionary обеспечивают "стилизованную" реализацию интерфейса IDictionary. Описания основных типов класса из этого пространства имен предлагаются в табл. 7.5.
Таблица 7.5.Типы пространства имен System.Collections.Specialized.
Тип |
Описание |
CollectionsUtil |
Создает коллекции, игнорирующие регистр символов в строках |
HybridDictionary |
Реализует IDictionary, используя ListDictionary, пока коллекция мала, и переключаясь на Hashtable, когда коллекция становится большой |
ListDictionary |
Реализует IDictionary, используя однонаправленный список. Рекомендуется для коллекций, которые содержат не более десятка элементов |
NameValueCollection |
Представляет отсортированную коллекцию связанных ключей и значений типа String, которые могут быть доступны или по ключу, или по индексу |
StringCollection |
Представляет коллекцию строк |
StringDictionary |
Реализует Hashtable с ключом, строго типизированным, как строка, а не объект |
StringEnumerator |
Поддерживает простой цикл по элементам StringCollection |
Интерфейс можно определить, как именованную коллекцию абстрактных членов. Ввиду того, что интерфейс не предлагает деталей реализаций, он обычно рассматривается, как, вариант поведения, возможного для данного типа. При реализации одного и того же интерфейса в нескольких классах вы получаете возможность обращаться с соответствующими типами одинаково (это называется интерфейсным полиморфизмом).
Для определения новых интерфейсов в C# предлагается ключевое слово interface. Любой тип может поддерживать столько интерфейсов, сколько необходимо, нужно только указать их в списке определения типа, разделяя запятыми. При этом можно создавать интерфейсы, которые оказываются производными нескольких базовых интерфейсов.
Помимо возможности создания пользовательских интерфейсов, вы имеете возможность использовать ряд стандартных интерфейсов, определенных в библиотеках .NET (т.е. предлагаемых каркасом приложений). Вы можете строить пользовательские типы, реализующие эти встроенные интерфейсы, чтобы обеспечить выполнение ряда стандартных действий, таких как клонирование, сортировка или перечисление. Наконец, в этой главе вы узнали о классах коллекций, определенных в пространстве имен System.Collections, и изучили ряд общих интерфейсов, которые используются связанными с коллекциями типами.
ГЛАВА 8. Интерфейсы обратного вызова, делегаты и события
До этого момента в нашей книге в каждом примере приложении программный код Main() тем или иным способом направлял запросы соответствующим объектам. Но мы пока что не рассматривали возможность обратного обращения объекта к вызывающей стороне. В большинстве программ типичным для объектов системы оказывается двухсторонняя коммуникация, которая реализуется с помощью интерфейсов обратного вызова, событий и других программных конструкций. Эта глава начинается с рассмотрения того, как с помощью типов интерфейса реализовать функциональные возможности обратного вызова.
Читать дальше