Главная » C# » Дополнительные приемы LINQ в Visual C# (Sharp)

0

LINQ не является единственным средством для фильтрации данных. С LINQ связо несколько методов расширения, которые можно применять для работы со спками. Например, чтобы отфильтровать определенный номер, можно было бы воользоваться следующим кодом:

int FrequencyOfANumberList(int numberToSearch) { var query = _tickets .Where (

(ticket, index) => ticket.Numbers[0] == numberToSearch

|| ticket.Numbers[l] == numberToSearch

|| ticket.Numbers[2] == numberToSearch

|| ticket.Numbers[3] == numberToSearch

|| ticket.Numbers[4] == numberToSearch

|| ticket.Numbers[5] == numberToSearch); return query.Count();

}

Концепции LINQ, такие как операторы from, where и select, не утрачены в этом коде; они просто не были использованы прямым образом. Функцию оператора from выполняет сама переменная „tickets, оператора where — метод where о, а оперора select — выбор по умолчанию, определяемый текущим узлом.

Для указания действия для метода where () применяется лямбда-выражение, котому передаются два параметра— объект и индекс объекта. Лямбда-выражение ожидает  возвращения  булевого  значения,  указывающего,  добавлять  ли  элемент в возвращенный список.

С помощью методов для работы со  списками, ассоциированных с типом, мы иользуем другую, чем LINQ, функциональность  в  абстрактном  смысле.  LINQ — это синтаксис, инкапсулирующий SQL-подобный текст. LINQ намного легче понать, и в нем намного легче программировать. Методы предоставляют дополнельную гибкость, но они более сложны в применении.

Например, чтобы вычислить частоту двух номеров в списке, можно воспользоватя следующим кодом:

int FrequencyOfTwoNumbersList(int numberlToSearch, int number2ToSearch) { var query = _tickets.Where(

(ticket, index) => ticket.Numbers[0] == numberlToSearch

|| ticket.Numbers[1] == numberlToSearch

|| ticket.Numbers[2] == numberlToSearch

|| ticket.Numbers[3] == numberlToSearch

|| ticket.Numbers[4] == numberlToSearch

|| ticket.Numbers[5] == numberlToSearch

).Where(

(ticket, index) => ticket.Numbers[0] == number2ToSearch

|| ticket.Numbers[1] == number2ToSearch

|| ticket.Numbers[2] == number2ToSearch

|| ticket.Numbers[3] == number2ToSearch

|| ticket.Numbers[4] == number2ToSearch

|| ticket.Numbers[5] == number2ToSearch); return query.Count();

}

Выделенная  жирным  шрифтом  строка кода демонстрирует использование  вывода одного  метода  в  качестве  ввода  для  другого  метода.   Такое  последовательное

соединение методов работает, т. к. метод обработки списка возвращает другие спки. Так, можно добавить множественные критерии, конкатенируя несколько вызов метода Where ().

Методы используются для фильтрования или манипуляции набором данных, где подробности метода предоставляются лямбда-выражением. В табл. 15.1 дано краое описание некоторых полезных методов для фильтрования и манипуляции спками. Лучшим способом изучения методов будет запустить Visual С# Express, объявить список и использовать IntelliSense, чтобы узнать имеющиеся методы. Также множество примеров, демонстрирующих различные методы для манипулии списками, можно найти на Web-странице http://msdn2.microsoft.com/en-us/ vcsharp/aa336746.aspx.

Таблица      15.1.     Некоторые      методы      для     работы      со      списками

Метод

Описание

Aggregate()

Возвращает сведения о списке.  Сведениями  может быть  количество четных чисел  или частота определенного числа.  Все элементы списка обрабатываются в цикле,  и результат возвращается в виде единствеого значения, а не списка

А11 0

Обрабатывает в цикле все элементы списка и в соответствии с лямбдыражением выполняет проверку на возвращение  true или  false. Прерка  может заключаться,  например,  в определении,  имеют ли  все объекты значение больше, чем  10.  Проверка должна  возвращать  true или  false только для отдельного объекта, а метод All ()  коррелирует все результаты и возвращает ответ для всего списка  в виде значения true ИЛИ false

Any()

То же самое, что и метод All ( ) , только проверка выполняется на сооетствие любого из элементов списка указанному условию.  При  положельном результате возвращается значение true, а при отрицателом — false

Average()

Вычисляет среднее  последовательности значений  и  возвращает рультат в  виде числового значения с двойной точностью.  Этот метод несколько странный, т.  к. для вычисления среднего нужны числа, хотя лямбда-выражение  может  вычислять  среднее  объектов

Cast()

Возвращает список,  в котором тип  каждого элемента  преобразован  из типа в списке в другой тип. Этот метод хорошо подходит для групповых преобразований  типа  экземпляров  списка

Concat()

Конкатенирует другой  список с текущим  списком

Contains()

Проверяет на  наличие определенного элемента  в списке.  Метод провяет каждым элемент списка с помощью лямбда-выражения  и  возврает true в случае успеха и  false в противном случае

ConvertAll()

Возвращает список,  в котором тип  каждого элемента преобразован  из типа в исходном списке в другой тип.  Этот метод хорошо подходит для групповых  преобразований типа  экземпляров  списка

Таблица      15.1      (окончание)

Метод

Описание

Distinct()

Удаляет все повторения в списке.  По умолчанию  реализация метода Distinct ()  проверяет на равенство,  вызывая сначала метод GetHashCode ( ) , а потом, если необходимо, метод Equals ( ) . Вариаом метода Distinct ()  будет проверить два типа на равенство с пощью экземпляра  интерфейса  iEqualityComparer. Но лучшим  поодом будет реализовать методы GetHashCode ()  и Equals ()

Except()

Выполняет операцию  разности  над текущим  и  переданным  списками и возвращает результат в виде нового набора данных.  Проверка на ренство идентична методу Distinct ()

Find()

Находит определенный элемент в списке.  Обратите внимание,  что при нахождении  элемента  используемое  лямбда-выражение  заставит  метод Find ()  прекратить дальнейшую обработку списка и  возвратить указаый  элемент

FindAll ()

Подобен методу Find(),  но находит множественные элементы  в списке. Сродни методу where ()

FindLast()

То же самое, что и Find ( ) , только поиск начинается с конца списка

ForEach()

Итератор,  использующий  лямбда-выражения для  обработки  каждого элемента списка.  Метод ForEach ()  является упрощенным  вариантом кода,  показанного  в  главе  9

GroupBy()

Разбивает список на  подгруппы,  как указано  предоставленным  лямбдыражением.  Например,  можно разбить оклад сотрудников фирмы  по группам

Intersect()

Определяет элементы,  общие для текущего  и  переданного  списков. Применяет такую же проверку на равенство,  как и метод Distinct ()

Max()

Определяет  максимальное  значение  списка

Mint)

Определяет  минимальное  значение  списка

Reverse ()

Изменяет порядок  списка  на  противоположный

Select()

Выбирает элемент из  списка,  отвечающий заданным  условиям

SelectMany()

Выбирает несколько элементов  из списка,  сохраняя  результат в другой список

Sum ()

Вычисляет сумму  элементов  списка

Union()

Выполняет объединение текущего  и  переданного списков.  Использует проверку на равенство, как для метода Distinct ()

ПРИМЕЧАНИЕ

В С# 3.0 возможности манипулирования списками претерпели драматические измения в лучшую сторону. Общая  структура  новых  возможностей  состоит  в  определии методов,  позволяющих разработчику  указывать  лямбда-выражение,  которое  пом соединяется в цепочку с  другими  методами.  Не  премините  уделить  время изучению  всех этих  возможностей.

В качестве примера мощи различных методов возьмем следующий код, который сжимает задачу вычисления частоты лотерейных номеров в пару строчек исходно кода:

int FrequencyOfANumberFunc(int numberToSearch) {  return _tickets.SelectMany((ticket) => ticket.Numbers

) .Where ((num) => num == numberToSearch) .Count () ,-

}

В примере информация каждого билета обрабатывается в цикле, вызывая метод SeiectMany (), который возвращает массив номеров, представляющий номера рыгрыша. Целью метода seiectManyO является объединение отдельных массивов номеров в один большой массив. Потом вызывается метод where (), чтобы оильтровать только те номера, которые совпадают с указанным, и, наконец, волняется подсчет найденных номеров, для чего вызывается метод Count ().

В последующих разделах рассматриваются примеры использования методов раирения с LINQ. Примеры реализованы в проекте консольного приложения LXNQExamples.

ПРИМЕЧАНИЕ

Для упрощения примеров в них  применяются  упрощенные  приемы  программировия. Вы увидите некоторые нерекомендуемые приемы программирования, такие как создание общих членов данных и  неупотребление свойств.

Источник: Гросс  К. С# 2008:  Пер. с англ. — СПб.:  БХВ-Петербург, 2009. — 576 е.:  ил. — (Самоучитель)

По теме:

  • Комментарии