|
Программирование >> Обработка исключительных ситуаций
Пусть исходный файл text. txt содержит строки Ехал Грека через реку. Видит Грека, в реке рак. Сунул Грека в реку руку, рак за руку Греку цап! Тогда результат работы программы будет выглядеть так:
Несколько пояснений к программе. В операторе 1 открывается текстовый файл, длина которого не должна превышать 32 767 символов, потому что в операторе 2 все его содержимое считывается в отдельную строку. ПРИМЕЧАНИЕ- Конечно, для реальной работы такой способ не рекомендуется. Кроме того, для файлов, открываемых для чтения, программа обязательно должна обрабатывать исключение FileNotFoundException (см. главу 11). В операторе 3 задается массив разделителей, передаваемый в качестве параметра методу Spl it, формирующему массив строк, каждая из которых содержит отдельное слово исходного файла. Этот массив используется для инициализации экземпляра words класса List<string>. Применение стандартного класса позволяет не заботиться о выделении места под массив слов. Оператор 5 описывает словарь, а в цикле 6 выполняется его заполнение путем просмотра списка слов words. Если слово встречается впервые, в значение, соответствующее слову как ключу, заносится единица. Если слово уже встречалось, значение увеличивается на единицу. В цикле 7 выполняется вывод словаря путем просмотра всех его ключей (для этого используется свойство словаря Keys, возвращающее коллекцию ключей) и в1-борки соответствующих значений. Метод Split не очень интеллектуален: он рассматривает пробел, расположенный после знака препинания, как отдельное слово. Для более точного разбиения на слова используются регулярные выражения, которые рассматриваются в главе 15. ПРИМЕЧАНИЕ Обратите внимание на то, насколько использование стандартнгх коллекций сокращает исходный текст программы. Конечно, на тщательное изучение их возможностей требуется много времени, однако это окупается многократно. Для полноты картины следует добавить, что наряду с параметризованными классами в пространстве имен System.Collections.Generic описаны параметризованные интерфейсы, перечисленные в табл. 13.6. Таблица 13.6. Параметризованные интерфейсы библиотеки .NET версии 2.0 Параметризованный интерфейс (версия 2.0) Обычный интерфейс
Создание класса-прототипа Язык C# позволяет создавать собственные классы-прототипы и их разновидности - интерфейсы, структуры, делегаты и события, а также обобщенные (generic) методы обычных классов. Рассмотрим создание класса-прототипа на примере стека, приведенном в спецификации С# . Параметр типа данных, которые хранятся в стеке, указывается в угловых скобках после имени класса, а затем используется таким же образом, как и обычные типы: public class Stack< Т[] items: int count; public void PushC T item ){...} оещение в стек public T PopO { ... } извлечение из стека При использовании этого класса на место параметра Т подставляется реальный тип, например int: Stack<int> stack - new Stack<int>(); stack.PushC 3 ) ; int x = stack.PopO; Тип Stack<int> называется сконструированным типом (constructed type). Этот тип создается во время выполнения программы при его первом упоминании в программе. Если в программе встретится класс Stack с другим значимым типом, например doubl е, среда выполнения создаст другую копию кода для этого типа. Напротив, для всех ссылочных типов будет использована одна и та же копия кода, поскольку работа с указателями на различные типы выполняется одинаковым образом. Создание конкретного экземпляра класса-прототипа называется инстанцированием. Класс-прототип может содержать произвольное количество параметров типа. Для каждого из них могут быть заданы ограничения (constraints), указывающие, каким требованиям должен удовлетворять аргумент, соответствующий этому параметру, например, может быть указано, что это должен быть значимый тип или тип, который реализует некоторый интерфейс. Синтаксически ограничения задаются после ключевого слова where, например: public class Stack< where T : struct { ... Здесь с помощью слова struct записано ограничение, что элементы стека должны быть значимого типа. Для ссылочного типа употребляется ключевое слово class. Для каждого типа, являющегося параметром класса, может быть задана одна строка ограничений, которая может включать один класс, а за ним - произвольное количество интерфейсов, перечисляемых через запятую. Указание в качестве ограничения имени класса означает, что соответствующий аргумент при инстанцировании может быть именем либо этого класса, либо его потомка. Указание имени интерфейса означает, что тип-аргумент должен реа-лизовывать данный интерфейс - это позволяет использовать внутри класса-прототипа, например, операции по перечислению элементов, их сравнению и т. п. Помимо класса и интерфейсов в ограничениях можно задать требование, чтобы тип-аргумент имел конструктор по умолчанию без параметров, что позволяет создавать объекты этого типа в теле методов класса-прототипа. Это требование записывается в виде выражения new(), например: public class EntityTablе<К,Е> where К: IComparable<K>, IPersistable where E: Entity. new() public void Add( К key. E entity ) { if ( key.CompareToC x ) < 0 ) { ... } В этом примере на первый аргумент класса EntityTable накладываются два ограничения по интерфейсам, а для второго аргумента задано, что он может быть только классом Entity или его потомком и иметь конструктор без параметров.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |