Читать книгу Programowanie funkcyjne w języku C#. Jak pisać lepszy kod - Enrico Buonanno - Страница 18
1.2.1 Funkcyjna natura LINQ
ОглавлениеGdy wypuszczono C# 3 wraz z wersją 3.5 .NET Framework, obejmował on wiele funkcji inspirowanych językami funkcyjnymi, w tym bibliotekę LINQ (System.Linq) oraz trochę nowych funkcji języka umożliwiających lub rozszerzających to, co dało się zrobić z LINQ, jak metody rozszerzające i drzewa wyrażeń.
LINQ jest w istocie biblioteką funkcyjną – co zapewne każdy zauważył. Używałem LINQ wcześniej, aby pokazać obie zasady FP – a jej funkcyjna natura staje się bardziej oczywista w miarę czytania tej książki.
LINQ oferuje implementacje wielu popularnych działań na listach (lub, ogólniej mówiąc, „sekwencjach”, jak instancje typu IEnumerable powinny być określane), a wśród nich odwzorowywanie, sortowanie i filtrowanie (patrz ramka „Typowe działania na ciągach”). Oto przykład łączący wszystkie trzy elementy:
Enumerable.Range(1, 100).
Where(i => i % 20 == 0).
OrderBy(i => -i).
Select(i => $"{i}%")
// => ["100%", "80%", "60%", "40%", "20%"]
Zauważmy jak Where, OrderBy, i Select przyjmują funkcje jako argumenty i nie zmieniają podanej kolekcji IEnumerable, a w to miejsce zwracają nową IEnumerable, ilustrując obie pokazane wcześniej reguły FP.
LINQ ułatwia przeszukiwanie obiektów nie tylko w pamięci (LINQ to Objects), ale też w różnych innych źródłach danych, jak tabele w bazach SQL i dane XML. Programiści C# przyjęli LINQ jako standardowy zestaw narzędzi do pracy na listach i danych relacyjnych (co obejmuje znaczącą ilość typowego kodu). Plusem jest to, że mamy już pewne pojęcie o tym, jak wygląda API biblioteki funkcyjnej.
Z drugiej strony, pracując z innymi typami, programiści C# trzymają się zwykle stylu imperatywnego, używając instrukcji sterowania przepływem do wyrażania zachowania programu. W rezultacie większość kodu C#, który widziałem, jest zwykle zlepkiem stylu funkcyjnego (przy pracy z IEnumerablei IQueryable) i imperatywnego (cała reszta).
Oznacza to, że choć programiści C# są świadomi korzyści wynikających z używania biblioteki funkcyjnej takiej jak LINQ, nie mieli wystarczająco dużo styczności z podstawowymi zasadami LINQ, aby wykorzystywać te techniki w swoich własnych projektach. Tym problemem ma zająć się ta książka.
Typowe działania na ciągachBiblioteka LINQ zawiera wiele metod służących do wykonywania podstawowych działań na ciągach, jak wymienione niżej.■ Odwzorowywanie – Mając dany ciąg i funkcję, odwzorowywanie daje nowy ciąg z elementami otrzymanymi przez zastosowanie danej funkcji na każdym elemencie danego ciągu (w LINQ robi się to za pomocą metody Select).Enumerable.Range(1, 3).Select(i => i * 3) // => [3, 6, 9]■ Filtrowanie – Mając dany ciąg i predykat, filtrowanie daje nowy ciąg złożony z elementów danego ciągu, które są zgodne z predykatem (w LINQ to Where).Enumerable.Range(1, 10).Where(i => i % 3 == 0) // => [3, 6, 9]■ Sortowanie – Mając dany ciąg i funkcję klucza wyboru, sortowanie daje nowy ciąg uporządkowany zgodnie z kluczem (w LINQ są to OrderBy i OrderByDescending).Enumerable.Range(1, 5).OrderBy(i => -i) // => [5, 4, 3, 2, 1] |