Я думаю многим читателям блога .Net знакомо имя Jon Skeet. Особенно после вчерашнего прошлогоднего поста юзера SergeyT. Поэтому я не буду повторять про сравнение с Чаком Норрисом и первое место по карме на StackOverflow.com. А вот упомянуть лишний раз про его замечательную книгу  “C# In Depth” точно лишним не будет. Центральное место в ней занимает LINQ вообще и LINQ to Objects в частности. Джон очень обстоятельно описывает все возможности языка C# и платформы .Net, которые сделали возможным появление LINQ в его нынешнем виде, а также подробности его реализации. Именно после прочтения этой книги я стал активно использовать LINQ to Objects в своих проектах. Однако в стандартной библиотеке не хватает нескольких крайне нужных операторов. К счастью, Джон Скит исправил это недоразумение. Так появилась небольшая, но очень полезная библиотка morelinq. А с конца прошлого года она доступна в виде NuGet-пакета. 
Большинство операторов перегружены для большей гибкости использования (например, можно задать свой IComparer и т.п.). Кроме перечисленных операторов, имеются еще два отладочных – AssertCount (проверяют количество элементов последовательности) и Trace (выводит все элементы в debug-консоль).
Вместе с исходниками библиотеки идет прекрасная документация в стиле MSDN, в которой подробно описаны все операторы, их параметры и имеются примеры использования. Также есть комментарии в исходном коде.
В заключение хочу обратить внимание читателей на две другие библиотеки авторства Джона Скита – MiscUtils и NodaTime (NuGet Package). Особенно интересна последняя – библиотека предназначена для работы с датой/временем. Джон занимался ей последние несколько лет и в ноябре прошлого года наконец выпустил версию 1.0. В его блоге можно почитать много интересного на тему того, чем плохи для этих целей стандартные классы .Net и какие подводные грабли поджидают разработчика, серьезно работающего со временем.
UPD: Перевод статьи про NodaTime.
UPD2: Я не стал использовать в статье слово «проекция», так как по-моему оно не употребляется в русскоязычном сообществе. Хотелось бы увидеть ваше мнение в опросе и комментариях.
Операторы библиотеки morelinq
| Batch | Превращает одну последовательность в несколько последовательностей по n элементов. | 
| Concat | Присоединяет элемент к коллекции либо коллекцию к элементу. | 
| Consume | «Поглощает» коллекцию, не производя никаких действий над элементами. | 
| DistinctBy | Возвращает только уникальные элементы (по заданному критерию). | 
| EquiZip | Создает новую последовательность, где каждый элемент создается на основе соответствующих элементов исходных последовательностей. Если последовательности имеют различное количество элементов, будет брошено исключение InvalidOperationException. | 
| ExceptBy | Возвращает элементы первой последовательности, которые не содержатся во второй (по заданному критерию). | 
| ForEach | Выполняет действие над каждым элементом последовательности. | 
| Generate | Генерирует последовательности по начальному элементу и функции-генератору. | 
| GenerateByIndex | Генерирует последовательность по индексам элементов. | 
| GroupAdjacent | Подобен GroupBy, но в группу попадают только идущие подряд элементы. | 
| Index | Возвращает последовательность пар индекс-значение. | 
| MaxBy | Возвращает максимальный элемент последовательности по заданному критерию. | 
| MinBy | Возвращает минимальный элемент последовательности по заданному критерию. | 
| Pad | Если количество элементов последовательности меньше заданного, дополняет последовательность значениями по умолчанию до заданного количества. | 
| Pairwise | Возвращает последовательность результатов функции текущего и предыдущего элемента (не применяется к первому элементу). | 
| Pipe | Возвращает исходную последовательность, выполняя Action над каждым элементом. | 
| Prepend | Дополняет начало коллекции заданным элементом. | 
| PreScan | Возвращает последовательность исходной длины, в которой N-й элемент определяется применением заданного преобразования к N-1 элементов. | 
| Scan | Возвращает последовательность исходной длины, в которой N-й элемент определяется применением заданного преобразования к N элементов. | 
| SingleOrFallback | Возвращает единственный элемент последовательности либо результат заданного делегата, если последовательность пуста. | 
| SkipUntil | Пропускает элементы исходной последовательности, пока заданное условие не станет истинным. Текущий элемент будет последним пропущенным. | 
| Split | Разделяет последовательность заданным разделителем (возвращает последовательность последовательностей). | 
| TakeEvery | Возвращает каждый N-й элемент исходной последовательности. | 
| TakeLast | Возвращает последние N элементов исходной последовательности. | 
| TakeUntil | Возвращает элементы исходной последовательности, пока заданное условие не станет истинным. Текущий элемент будет последним возвращенным. | 
| ToDataTable | Позволяет преобразовать последовательность в новую DataTable или заполнить имеющуюся. Есть возможность задать лямдами получение из исходного элемента значений для полей таблицы. | 
| ToDelimitedString | Преобразует последовательность в строку с разделителями (то что обычно приходится делать через нудный Aggregate). | 
| ToHashSet | Возвращает HashSet〈T&кang; от исходных элементов. | 
| Zip | То же, что EquiZip, но длина результирующей последовательности будет равна длине наименьшей из исходных. | 
| ZipLongest | То же, что EquiZip, но длина результирующей последовательности будет равна длине наибольшей из исходных (в качестве недостающих значений б��дет использовано значение по умолчанию). | 
Большинство операторов перегружены для большей гибкости использования (например, можно задать свой IComparer и т.п.). Кроме перечисленных операторов, имеются еще два отладочных – AssertCount (проверяют количество элементов последовательности) и Trace (выводит все элементы в debug-консоль).
Вместе с исходниками библиотеки идет прекрасная документация в стиле MSDN, в которой подробно описаны все операторы, их параметры и имеются примеры использования. Также есть комментарии в исходном коде.
В заключение хочу обратить внимание читателей на две другие библиотеки авторства Джона Скита – MiscUtils и NodaTime (NuGet Package). Особенно интересна последняя – библиотека предназначена для работы с датой/временем. Джон занимался ей последние несколько лет и в ноябре прошлого года наконец выпустил версию 1.0. В его блоге можно почитать много интересного на тему того, чем плохи для этих целей стандартные классы .Net и какие подводные грабли поджидают разработчика, серьезно работающего со временем.
UPD: Перевод статьи про NodaTime.
UPD2: Я не стал использовать в статье слово «проекция», так как по-моему оно не употребляется в русскоязычном сообществе. Хотелось бы увидеть ваше мнение в опросе и комментариях.
Only registered users can participate in poll. Log in, please.
Понятно ли было бы слово «проекция» в описании операторов morelinq? (например, DistinctBy в документации описывается как «Returns all distinct elements of the given source, where 'distinctness' is determined via a projection and the default eqaulity comparer for the projected type.»
68.83%Да53
31.17%Нет24
 77 users voted.    34 users abstained. 

