Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Класи-прототипи




 

Багато алгоритмів не залежать від типів даних, з якими вони працюють. Простими прикладами можуть служити сортування і пошук. Можливість відокремити алгоритми від типів даних надають класи-прототипи (generics) - класи, що мають як параметри типи даних. Найчастіше ці класи застосовуються для зберігання даних, тобто як контейнерні класи, або колекції.

У другу версію бібліотеки.NET додані колекції, що параметризуються, для представлення основних структур даних - стека, черги, списку, словника і так далі. Ці колекції, розташовані в просторі імен System.Collections.Generic, дублюють аналогічні колекції простору імен System.Collections, розглянуті в розділі “Простір імен System.Collections ”. У таблиці 13.5 приводиться відповідність між звичайними та парамеризованими колекціями бібліотеки.NET (параметри, що визначають типи даних, що зберігаються в колекції, вказані в кутових дужках).

Таблиця 13.5

Параметризовані колекції бібліотеки.NET

 

Клас-прототип Звичайний клас
Comparer<T> Comparer
Dictionary<K,T> HashTable
LinkedList<T> --
List<T> ArrayList
Queue<T> Queue
SortedDictionary<K,T> SortedList
Stack<T> Stack

 

У колекцій, описаних в бібліотеці.NET версій 1.0 і 1.1, є два основні недоліки, обумовлених тим, що в них зберігаються посилання на тип object:

· у одній і тій же колекції можна зберігати елементи будь-якого типу, отже, помилки при переміщенні в колекцію неможливо проконтролювати на етапі компіляції, а при витяганні елементу потрібне його явне перетворення;

· при зберіганні в колекції елементів значущих типів виконується великий об'єм дій з упаковки і розпаковування елементів, що в значній мірі знижує ефективність роботи.

Параметром класу-прототипу є тип даних, з яким він працює. Це позбавляє від перерахованих недоліків. Як приклад розглянемо застосування універсального “двійника” класу Arraylist - класу List<t> - для зберігання колекції об'єктів класів Monster і Daemon, а також для зберігання цілих чисел.

Лістинг 13.2. Використання універсальної колекції List<T>

using System;

using System.Collections.Generic;

using System.Text;

 

namespace ConsoleApplication1

{

using MonsterLib;

class Program

{

static void Main()

{

List<Monster> stado = new List<Monster>();

stado.Add(new Monster("Monia"));

stado.Add(new Monster("Monk"));

stado.Add(new Daemon ("Dimon", 3));

foreach (Monster x in stado) x.Passport();

List<int> lint = new List<int>();

lint.Add(5); lint.Add(1); lint.Add(3);

lint.Sort();

int a = lint[2];

Console.WriteLine(a);

foreach (int x in lint) Console.Write(x + " ");

}

}

}

 

Результат роботи програми:

Monster Monia health = 100 ammo = 100

Monster Monk health = 100 ammo = 100

Daemon Dimon health = 100 ammo = 100 brain = 3

1 3 5

 

У лістингу 13.2 дві колекції. Перша (stado) містить елементи, що призначені для користувача класів, які знаходяться в бібліотеці Monsterlib.dll, створеною в попередньому розділі. У колекції, для якої оголошений тип елементів Monster, завдяки поліморфізму можна зберігати елементи будь-якого похідного класу, але не елементи інших типів.

Здавалося б, в порівнянні із звичайними колекціями це обмеження, а не універсальність, проте на практиці колекції, в яких дійсно потрібно зберігати значення різних, не зв'язаних між собою типів, майже не використовуються. Гідністю ж такого обмеження є те, що компілятор може виконати контроль типів під час компіляції, а не виконання програми, що підвищує її надійність і спрощує пошук помилок.

Колекція int складається з цілих чисел, причому для роботи з ними не потрібні ні операції упаковки і розпаковування, ні явні перетворення типу при отриманні елементу з колекції, як це було в звичайних колекціях (див. лістинг 13.1).

Класи-прототипи називають також родовими або шаблонними, оскільки вони є зразками, по яких під час виконання програми будуються конкретні класи. При цьому відомості про класи, які є параметрами класів-прототипів, витягуються з метаданих.

Використання стандартних параметризованих колекцій для зберігання і обробки даних є хорошим стилем програмування, оскільки дозволяє скоротити терміни розробки програм і підвищити їх надійність.

У лістингу 13.3 приведений ще один приклад застосування параметризованих колекцій. Програма зчитує вміст текстового файлу, розбиває його на слова і підраховує кількість повторень кожного слова в тексті. Для зберігання слів і числа їх повторень використовується словник Dictionary<T,K>. У цього класу два параметри: тип ключів і тип значень, що зберігаються у словнику. Як ключі використовуються слова, зчитані з файлу, а значеннями є лічильники цілого типу, які збільшуються на одиницю, коли слово зустрічається в черговий раз.

Лістинг 13.3. Формування частотного словника

 

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

namespace ConsoleApplicationl

{

class Program

{

static void Main()

{

StreamReader f = new StreamReader(@"d:\C#\text.txt"); //1

string s = f.ReadToEnd(); // 2

char[] separators = {'.', ' ', ',', '!' }; //3

List<string> words = new List<string> (s.Split(separators)); //4

Dictionary<string, int> map = new Dictionary<string, int>(); //5

 

foreach (string w in words) //6

{

if (map.ContainsKey(w)) map[w]++;

else map[w] = 1;

}

foreach (string w in map.Keys) //7

Console.WriteLine("{0}\t{1}", w, map[w]);

}

}

}

Нехай початковий файл text. txt містить рядки:

Ехал Грека через реку. Видит Грека, в реке рак.

Сунул Грека в реку руку, рак за руку Греку цап!

 

Тоді результат роботи програми виглядатиме так:

 

Ехал  
Грека  
через  
реку  
   
Видит  
в  
реке  
рак  
   
Сунул  
руку  
за  
Греку  
цап  

Декілька пояснень до програми. У операторові 1 відкривається текстовий файл, довжина якого не повинна перевищувати 32767 символів, тому що в операторові 2 весь його вміст зчитується в окремий рядок.

Звичайно, для реальної роботи такий спосіб не рекомендується. Крім того, для файлів, що відкриваються для читання, програма обов'язково повинна обробляти виключення FileNotFoundException.

У операторові 3 задається масив роздільників, переданий як параметр методу Split, що формує масив рядків, кожен з яких містить окреме слово початкового файлу. Цей масив використовується для ініціалізації екземпляра words класу List<string>. Застосування стандартного класу дозволяє не піклуватися про виділення місця під масив слів.

Оператор 5 описує словник, а в циклі 6 виконується його заповнення шляхом перегляду списку слів words. Якщо слово зустрічається вперше, в значення, відповідне слову як ключу, заноситься одиниця. Якщо слово вже зустрічалося, значення збільшується на одиницю.

У циклі 7 виконується виведення словника шляхом перегляду всіх його ключів (для цього використовується властивість словника Keys, що повертає колекцію ключів) і вибірки відповідних значень.

Метод Split не дуже інтелектуальний: він розглядає пропуск, розташований після розділового знаку, як окреме слово. Для точнішого розбиття на слова використовуються регулярні вирази, які розглядаються в наступному розділі.

Зверніть увагу на те, наскільки використання стандартних колекцій скорочує початковий текст програми. Звичайно, на ретельне вивчення їх можливостей потрібно багато часу, проте це окупається багато разів.

Для повноти картини слід додати, що разом з параметризованими класами в просторі імен System.Collections.Generic описані параметризовані інтерфейси, які перераховані в таблиці 13.6.

Таблиця 13.6

 

Параметризовані інтерфейси бібліотеки.NET

 

Парамеризований інтерфейс Звичайний інтерфейс
ICollection<T> ICollection
IComparable<T> IComparable
IDictionary<K,T IDictionary
IEnumerable<T> IEnumerable
IEnumerator<T> IEnumerator
IList<T> IList

 




Поделиться с друзьями:


Дата добавления: 2014-12-27; Просмотров: 446; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.007 сек.