- •А.А. Волосевич
- •1. Работа с Числами
- •2. Дата и время
- •3. Работа со строками и текстом
- •4. Преобразование информации
- •5. Отношения равенства и порядка
- •Сравнение для выяснения равенства
- •Сравнение для выяснения порядка
- •6. Жизненный цикл объектов
- •Алгоритм «сборки мусора»
- •Финализаторы и интерфейс iDisposable
- •7. Перечислители и итераторы
- •8. Интерфейсы стандартных коллекций
- •9. Массивы и класс system.Array
- •10. Типы для работы с коллекциями-списками
- •11. Типы для работы с коллекциями-множествами
- •12. Типы для работы с коллекциями-словарями
- •13. Типы для создания пользовательских коллекций
- •14. Технология linq to objects
- •1. Оператор условия Where().
- •2. Операторы проекций.
- •3. Операторы упорядочивания.
- •4. Оператор группировки GroupBy().
- •5. Операторы соединения.
- •6. Операторы работы с множествами.
- •7. Операторы агрегирования.
- •8. Операторы генерирования.
- •9. Операторы кванторов и сравнения.
- •10. Операторы разбиения.
- •11. Операторы элемента.
- •12. Операторы преобразования.
- •15. Работа с объектами файЛовой системы
- •16. Ввод и вывод информации
- •Потоки данных и декораторы потоков
- •2. Классы для работы с потоками, связанными с хранилищами.
- •3. Декораторы потоков.
- •4. Адаптеры потоков.
- •Адаптеры потоков
- •17. Основы xml
- •18. Технология linq to xml
- •Создание, сохранение, загрузка xml
- •Запросы, модификация и трансформация xml
- •Пространства имён xml
- •19. ДОполнительные возможности обработки xml
- •20. Сериализация
- •Сериализация времени выполнения
- •Сериализация контрактов данных
- •21. Состав и взаимодействие сборок
- •22. Метаданные и получение информации о типах
- •23. Позднее связывание и кодогенерация
- •24. Динамические типы
- •25. Атрибуты
- •26. Файлы конфигуРации
- •27. Основы мНогопоточноГо программирования
- •28. Синхронизация потоков
- •29. Библиотека параллельных расширений
- •Параллелизм на уровне задач
- •Параллелизм при императивной обработке данных
- •Параллелизм при декларативной обработке данных
- •Обработка исключений и отмена выполнения задач
- •Коллекции, поддерживающие параллелизм
- •30. Асинхронный вызов методов
- •31. Процессы и домены
- •32. Безопасность
- •Разрешения на доступ
- •Изолированные хранилища
- •Криптография
- •33. Диагностика
5. Операторы соединения.
Операторы соединения применяются, когда требуется соединить две коллекции, элементы которых имеют общие атрибуты. Основным оператором соединения является оператор Join().
IEnumerable<V> Join<T, U, K, V>(this IEnumerable<T> outer,
IEnumerable<U> inner,
Func<T, K> outerKeySelector,
Func<U, K> innerKeySelector,
Func<T, U, V> resultSelector);
Как видим, оператор Join() требует задания двух коллекций (внешней и внутренней) и трёх функций. Первая функция порождает ключ из элемента внешней коллекции, вторая – из элемента внутренней коллекции, а третья функция продуцирует объект коллекции-результата. При выполнении соединения Join() итерируется по внешней коллекции и ищет соответствия с элементами внутренней коллекции. При этом возможны следующие ситуации:
-
Найдено одно соответствие – в результат включается один элемент.
-
Найдено множественное соответствие – результат содержит по элементу для каждого соответствия.
-
Соответствий не найдено – элемент не входит в результат.
Рассмотрим примеры использования оператора Join(). Для этого опишем коллекцию cit объектов класса Citizen.
public class Citizen
{
public int BirthYear { get; set; }
public string IDNumber { get; set; }
}
int year = DateTime.Now.Year;
var cit = new List<Citizen> {
new Citizen {BirthYear = year - 17, IDNumber = "KLM897"},
new Citizen {BirthYear = year - 18, IDNumber = "WEF442"},
new Citizen {BirthYear = year - 18, IDNumber = "HHH888"},
new Citizen {BirthYear = year - 25, IDNumber = "XYZ012"}};
Выполним оператор Join():
var r1 = gr.Join(cit, s => year - s.Age, c => c.BirthYear,
(s, c) => new {s.Name, c.IDNumber});
// r1 содержит следующие объекты:
// {Name = "Smirnov", IDNumber = "WEF442"}
// {Name = "Smirnov", IDNumber = "HHH888"}
// {Name = "Kuznetsov", IDNumber = "WEF442"}
// {Name = "Kuznetsov", IDNumber = "HHH888"}
Оператор GroupJoin() порождает набор, группируя элементы внутренней коллекции при нахождении соответствия с элементом внешней коллекции: Если же соответствие не найдено, в результат включается пустая группа.
IEnumerable<V> GroupJoin()<T, U, K, V>(this IEnumerable<T> outer,
IEnumerable<U> inner,
Func<T, K> outerKeySelector,
Func<U, K> innerKeySelector,
Func<T, IEnumerable<U>, V> resultSelector);
Ниже приведён пример использования GroupJoin().
var r3 = cit.GroupJoin(gr, c => c.BirthYear, s => year - s.Age,
(c, group) => new { c.IDNumber,
Names = group.Select(s => s.Name) });
foreach (var data in r3)
{
Console.WriteLine(data.IDNumber);
foreach (string s in data.Names)
{ // 1-я и 4-я группы пусты,
Console.WriteLine(s); // 2-я и 3-я содержат два элемента
}
}
Оператор Zip() порождает набор на основе двух исходных коллекций, выполняя заданное генерирование элементов. Длина результирующей коллекции равна длине меньшей из двух исходных коллекций.
IEnumerable<V> Zip<T, U, V>(this IEnumerable<T> first,
IEnumerable<U> second,
Func<T, U, V> resultSelector);
Дадим простейший пример использования Zip():
int[] numbers = { 1, 2, 3, 4 };
string[] words = { "one", "two", "three" };
var res = numbers.Zip(words, (f, s) => f + " " + s); // 3 элемента