Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
1391-1497.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
126.26 Кб
Скачать

Int Compare(т х, т у)

У цьому методі рівняються об'єкти х i y і повертається нульове значення, якщо значення порівнюваних об'єктів рівні; позитивне - якщо значення об'єкта х більше, ніж в об'єкта y; і негативне - якщо значення об'єкта х менше, ніж в об'єкта y.

Нижче наведена узагальнена версія попередньої програми обліку товарних запасів, у якій тепер використається інтерфейс IComparer<T>. Вона дає такий же результат, як і неузагальнена версія цієї ж програми.

// Використати узагальнений варіант інтерфейсу IComparer<T>. using System;

using System.Collection's .Generic;

// Створити об'єкт типу IComparer<T> для об'єктів класу Inventory, class CompInv<T> : IComparer<T> where T : Inventory {

// Реалізувати інтерфейс IComparer<T>. public int Compare(T x, T y) {

return string.Compare(x.name, y.name, StringComparison.Ordinal);

}

class Inventory { public string name; double cost; int onhand;

public Inventory(string n, double c, int h) { name = n; cost = c; onhand = h;

}

public override string ToStringf) { return

String.Format("(0,-10) Ціна: {1,6:З} У наявності: {2}", name, cost, onhand);

)

class GenericIComparerDemo { static void Main() {

CompInv<Inventory> comp = new CompInv<Inventory>();

List<Inventory> inv = new List<Inventory>();

// Додати елементи в список. inv.Add(new Inventory("Гострозубці", 5.95, 3));

Inv.Add(new Inventory("Викрутки", 8.29, 2)); inv.Add(new Inventory("Молотки", 3.50, 4)); inv.Add(new Inventory("Дриля", 19.88, 8));

Console.WriteLine("Перелік товарних запасів до сортування:"); foreach(Inventory i in inv) {

Console.WriteLine (" " + i);

)

Console.WriteLine ();

// Відсортувати список, використовуючи інтерфейс IComparer. inv.Sort(comp);

Console.WriteLine("Перелік товарних запасів після сортування:"); foreach(Inventory i in inv) {

Console.WriteLine (" " + i);

}

}

Застосування класу StringComparer

У простих прикладах із цієї глави вказувати явно спосіб порівняння символьних рядків зовсім не обов'язково. Але це може знадобитися в тих випадках, коли рядка зберігаються у відсортованій колекції або коли рядка шукаються або сортуються в колекції. Так, якщо рядки повинні бути відсортовані з урахуванням настроювань одного культурного середовища, а потім їх доводиться шукати з урахуванням настроювань іншого культурного середовища, то щоб уникнути помилок, найімовірніше, буде потрібно вказати спосіб порівняння символьних рядків. Аналогічна ситуація виникає й при хешировании колекції. Для подібних (і інших) випадків у конструкторах класів деяких колекцій передбачена підтримка параметра типу IComparer. З метою явно вказати спосіб порівняння символьних рядків цьому параметру передається як аргумент екземпляр об'єкта класу StringComparer.

Клас StringComparer був докладно описаний у главі 21 при розгляді питань сортування й пошуку в масивах. У цьому класі реалізуються інтерфейси IComparer, IComparer<String>, IEqualityComparer, а також IEqualityComparer<String>. Отже, екземпляр об'єкта типу StringComparer може бути переданий параметру типу IComparer як аргумент. У класі StringComparer визначається трохи доступних тільки для читання властивостей, що повертають екземпляр об'єкта типу StringComparer, що підтримує різні способи порівняння символьних рядків. Як пояснювалося в главі 21, до числа цих властивостей ставляться наступні: CurrentCulture, CurrentCulturelgnoreCase, InvariantCulture, InvariantCulturelgnoreCase, Ordinal, а також OrdinallgnoreCase. Всі ці властивості можна використати для явної вказівки способу порівняння символьних рядків.

Як приклад нижче показано, як колекція типу SortedListc<Key, TValue> конструюється для зберігання символьних рядків, ключі яких рівняються порядковим способом.

SortedList<string, int> users =

new SortedList<string, int>(StringComparer.Ordinal);

Доступ до колекції за допомогою перечисельника

До елементів колекції нерідко доводиться звертатися циклічно, наприклад, для відображення кожного елемента колекції. Із цією метою можна, з одного боку, організувати цикл foreach, як було показано в наведені вище прикладах, а з іншого боку - скористатися перечисельником. Перечисельник - це об'єкт, що реалізує неузагальнений інтерфейс IEnumerator або узагальнений інтерфейс IEnumerator<T>.

В інтерфейсі IEnumerator визначається одна властивість, Current, неузагальнена форма якого наведена нижче.

object Current { get; )

А в інтерфейсі IEnumerator<T> оголошується наступна узагальнена форма властивості Current.

Т Current { get; }

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

В інтерфейсі IEnumerator визначаються два методи. Першим з них є метод MoveNext (), що повідомляє в такий спосіб.

bool MoveNext()

При кожному виклику методу MoveNext () поточне положення перечисельника зміщається до наступного елемента колекції. Цей метод повертає логічне значення true, якщо наступний елемент колекції доступний, і логічне значення false, якщо досягнуть кінець колекції. Перед першим викликом методу MoveNext () значення властивості Current виявляється невизначеним. (У принципі до першого виклику методу MoveNext() перечисельник звертається до неіснуючого елемента, що повинен перебувати перед першим елементом колекції. Саме тому доводиться викликати метод MoveNext(), щоб перейти до першого елемента колекції.)

Для установки перечисельника у вихідне положення, що відповідає початку колекції, викликається наведений нижче метод Reset ().

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]