Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
opi.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.81 Mб
Скачать

Створення фільтруючих методів розширення

Останній аспект методів розширення, який ми хочемо згадати - можливість їх застосування для фільтрації колекцій об'єктів. Метод розширення, який діє по відношенню до інтерфейсу IEnumerable <T> і який також повертає IEnumerable <T>, може використовувати ключове слово yield, щоб застосувати критерій відбору до елементів у джерелі даних для створення зменшеного набору результатів. Такий метод показаний в лістингу 7.

Лістинг 7. Фільтруючий метод розширення

public static IEnumerable<Product> FilterByCategory(

this IEnumerable<Product> productEnum, string categoryParam) {

foreach (Product prod in productEnum) {

if (prod.Category == categoryParam) {

yield return prod;

}

}

}

Якщо використовується ключове слово yield в інструкції, то це означає , що метод , оператор або метод доступу get в якому воно зустрічається, є ітератором. Ітератор можна використовувати для виконання настроюваної ітерації по колекції (тобто для перебору елементів колекції). У наступному прикладі показано дві форми запису оператора yield:

yield return <expression> ;

yield break ;

Використовуйте вираз yield return для повернення по черзі кожного елемента.

Можна використовувати вираз yield break для завершення ітерації.

Метод-ітератор використовується, наприклад, в операторі foreach. Кожна ітерація циклу foreach викликає метод-ітератор. Коли в методі-ітераторі зустрічається оператор yield return, повертається вираз expression і зберігається поточне положення в коді. Виконання буде продовжено з цього місця розташування при черговому виклику функції ітератора.

Метод розширення FilterByCategory приймає додатковий параметр, який дозволяє вставляти умову фільтрації при виклику методу. Об'єкти Product, властивість Category яких відповідає параметру, повертаються в результаті IEnumerable <Product>, а ті, чия властивість не відповідає – відкидаються. Використання цього методу показано в лістингу 8.

Лістинг 8. Використання фільтруючого методу розширення

using System;

using System.Collections.Generic;

class Program {

static void Main(string[] args) {

// create and populate ShoppingCart

IEnumerable<Product> products = new ShoppingCart {

Products = new List<Product> {

new Product {Name = "Kayak", Category = "Watersports", Price = 275M},

new Product {Name = "Lifejacket", Category = "Watersports", Price = 48.95M},

new Product {Name = "Soccer ball", Category = "Soccer", Price = 19.50M},

new Product {Name = "Corner flag", Category = "Soccer", Price = 34.95M}

}

};

foreach (Product prod in products.FilterByCategory ("Soccer") ) {

Console.WriteLine ("Name: {0}, Price {1: c}", prod.Name, prod.Price);

}

}

}

При виклику методу FilterByCategory у відношенні до ShoppingCart повертаються тільки ті об'єкти Product, які відносяться до категорії Soccer. Після компіляції і виконання цього методу ми отримуємо наступні результати:

Name: Soccer ball, Price $ 19.50

Name: Corner flag, Price $ 34.95

І, звичайно, методи розширення можна використовувати подібно будь-яким іншим і об'єднувати їх в ланцюжки. Наприклад, можна відфільтрувати об'єкти Product, які належать до категорії Soccer, а потім передати результати методу TotalPrices, щоб додати їх до значення властивості Price, як показано в лістингу 9.

Лістинг 9. Об'єднання методів розширення в ланцюжок

decimal total = products.FilterByCategory ("Soccer"). TotalPrices ();

Console.WriteLine ("Filtered total: {0: c} ", total);

Нижче показаний результат виконання цих операторів:

Filtered total: $ 54.45

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