Szybko przeczytałem dokumentację Microsoft Lambda Expression .
Ten rodzaj przykładu pomógł mi lepiej zrozumieć:
delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
Mimo to nie rozumiem, dlaczego to taka innowacja. To tylko metoda, która umiera, gdy kończy się „zmienna metody”, prawda? Dlaczego powinienem używać tego zamiast prawdziwej metody?
delegate
jest C #, gorąco polecam przeczytanie tego przed przeczytaniem reszty tej strony: stackoverflow.com/questions/2082615/…Odpowiedzi:
Wyrażenia lambda są prostszą składnią dla anonimowych delegatów i mogą być używane wszędzie tam, gdzie można użyć anonimowego delegata. Jednak przeciwieństwo nie jest prawdą; wyrażenia lambda można konwertować na drzewa wyrażeń, co pozwala na wiele magii, takich jak LINQ na SQL.
Poniżej znajduje się przykład wyrażenia LINQ do Objects przy użyciu anonimowych delegatów, a następnie wyrażeń lambda, aby pokazać, o ile są one łatwiejsze dla oka:
Wyrażenia lambda i anonimowi delegaci mają przewagę nad pisaniem osobnej funkcji: implementują zamknięcia, które pozwalają przekazać stan lokalny do funkcji bez dodawania parametrów do funkcji lub tworzenia obiektów jednorazowego użytku.
Drzewa wyrażeń to nowa, bardzo potężna funkcja C # 3.0, która pozwala interfejsowi API spojrzeć na strukturę wyrażenia zamiast po prostu uzyskać odwołanie do metody, którą można wykonać. Interfejs API musi po prostu przekształcić parametr delegowany w
Expression<T>
parametr, a kompilator wygeneruje drzewo wyrażeń z lambda zamiast anonimowego delegata:nazywany jak:
staje się:
Ten ostatni przejdzie reprezentację abstrakcyjnego drzewa składni, która opisuje wyrażenie
x > 5
. LINQ do SQL polega na tym zachowaniu, aby móc włączyć wyrażenia C # w wyrażenia SQL wymagane do filtrowania / zamawiania / itp. Po stronie serwera.źródło
Anonimowe funkcje i wyrażenia są przydatne w przypadku metod jednorazowych, które nie korzystają z dodatkowej pracy wymaganej do stworzenia pełnej metody.
Rozważ ten przykład:
przeciw
Są to funkcjonalnie równoważne.
źródło
Uznałem je za przydatne w sytuacji, gdy chciałem zadeklarować moduł obsługi dla jakiegoś zdarzenia kontrolnego, używając innej kontrolki. Aby to zrobić normalnie, musisz przechowywać referencje kontrolek w polach klasy, abyś mógł użyć ich w innej metodzie niż zostały utworzone.
dzięki wyrażeniom lambda możesz używać go w następujący sposób:
Dużo łatwiej.
źródło
Lambda usunął na przykład anonimową składnię delegatów C # 2.0
Wykonano w C # 2.0 w następujący sposób:
Funkcjonalnie robią dokładnie to samo, jest to po prostu bardziej zwięzła składnia.
źródło
To tylko jeden ze sposobów użycia wyrażenia lambda. Możesz użyć wyrażenia lambda w dowolnym miejscu, w którym możesz użyć delegata. To pozwala robić takie rzeczy:
Ten kod przeszuka listę w poszukiwaniu hasła pasującego do słowa „cześć”. Innym sposobem na to jest przekazanie delegata do metody Find, jak poniżej:
EDYTOWAĆ :
W C # 2.0 można to zrobić za pomocą anonimowej składni delegatów:
Lambda znacznie wyczyściła tę składnię.
źródło
string
a zwraca abool
) jako parametrFind
samej metody.Microsoft dał nam czystszy, wygodniejszy sposób tworzenia anonimowych delegatów zwanych wyrażeniami Lambda. Jednak niewiele uwagi poświęca się części wyrażeń tego wyrażenia. Microsoft wydał całą przestrzeń nazw System.Linq.Expressions , która zawiera klasy do tworzenia drzew wyrażeń opartych na wyrażeniach lambda. Drzewa wyrażeń składają się z obiektów reprezentujących logikę. Na przykład x = y + z jest wyrażeniem, które może być częścią drzewa wyrażeń w .Net. Rozważ następujący (prosty) przykład:
Ten przykład jest trywialny. I jestem pewien, że myślisz: „Jest to bezużyteczne, ponieważ mógłbym bezpośrednio utworzyć delegata zamiast tworzyć wyrażenie i kompilować je w czasie wykonywania”. I miałbyś rację. Ale to stanowi podstawę dla drzewek ekspresyjnych. Istnieje wiele wyrażeń dostępnych w przestrzeni nazw wyrażeń i możesz zbudować własne. Myślę, że możesz zauważyć, że może to być przydatne, gdy nie wiesz dokładnie, jaki algorytm powinien być w czasie projektowania lub kompilacji. Widziałem gdzieś przykład użycia tego do napisania kalkulatora naukowego. Możesz także użyć go do systemów bayesowskich lub do programowania genetycznego(AI). Kilka razy w mojej karierze musiałem napisać funkcjonalność podobną do Excela, która pozwoliła użytkownikom na wprowadzanie prostych wyrażeń (dodawanie, dodawanie podmian itp.) W celu obsługi dostępnych danych. W wersji pre-.Net 3.5 musiałem skorzystać z jakiegoś języka skryptowego zewnętrznego dla C # lub musiałem użyć funkcji emitowania kodu w refleksji, aby stworzyć kod .Net w locie. Teraz użyłbym drzewek wyrażeń.
źródło
Pozwala to uniknąć konieczności definiowania metod, które są używane tylko raz w określonym miejscu, z dala od miejsca, w którym są używane. Dobrym zastosowaniem są komparatory dla ogólnych algorytmów, takich jak sortowanie, w których można następnie zdefiniować niestandardową funkcję sortowania, w której wywołuje się sortowanie, a nie zmuszać do szukania gdzie indziej sortowania.
I to nie jest tak naprawdę innowacja. LISP ma funkcje lambda od około 30 lat lub dłużej.
źródło
Można również znaleźć użycie wyrażeń lambda w pisaniu ogólnych kodów, aby działać zgodnie z twoimi metodami.
Na przykład: Funkcja ogólna do obliczania czasu potrzebnego na wywołanie metody. (tj.
Action
tutaj)I możesz wywołać powyższą metodę za pomocą wyrażenia lambda w następujący sposób:
Wyrażenie pozwala uzyskać wartość zwracaną z metody i również parametry
źródło
Wyrażenie lambda to zwięzły sposób reprezentowania anonimowej metody. Zarówno metody anonimowe, jak i wyrażenia Lambda pozwalają na zdefiniowanie implementacji metody bezpośrednio, jednak metoda anonimowa wyraźnie wymaga zdefiniowania typów parametrów i typu zwracanego dla metody. Wyrażenie Lambda korzysta z funkcji wnioskowania o typie w C # 3.0, która pozwala kompilatorowi wnioskować o typie zmiennej na podstawie kontekstu. Jest to bardzo wygodne, ponieważ oszczędza nam dużo pisania!
źródło
Wyrażenie lambda jest jak anonimowa metoda napisana zamiast instancji delegowanej.
Rozważ wyrażenie lambda
x => x * x;
Kod wyrażenia lambda może być blokiem instrukcji zamiast wyrażenia.
Przykład
Uwaga:
Func
jest predefiniowanym ogólnym delegatem.Bibliografia
źródło
Często używasz tej funkcji tylko w jednym miejscu, więc stworzenie metody po prostu zaśmieca klasę.
źródło
Jest to sposób na wykonanie niewielkiej operacji i umieszczenie jej bardzo blisko miejsca, w którym jest używana (podobnie jak deklarowanie zmiennej w pobliżu jej punktu użycia). Ma to na celu zwiększenie czytelności kodu. Anonimizując wyrażenie, znacznie utrudniasz komuś złamanie kodu klienta, jeśli funkcja jest używana gdzie indziej i zmodyfikowana w celu „ulepszenia”.
Podobnie, dlaczego musisz używać foreach? Możesz zrobić wszystko w foreach za pomocą zwykłej pętli for lub po prostu używając IEnumerable bezpośrednio. Odpowiedź: nie potrzebujesz go, ale dzięki temu twój kod jest bardziej czytelny.
źródło
Innowacja polega na bezpieczeństwie i przejrzystości. Chociaż nie deklarujesz typów wyrażeń lambda, są one wywnioskowane i mogą być używane przez wyszukiwanie kodu, analizę statyczną, narzędzia refaktoryzacji i odbicie środowiska uruchomieniowego.
Na przykład, zanim mógłeś użyć SQL i uzyskać atak wstrzykiwania SQL, ponieważ haker przekazał ciąg znaków, w którym zwykle oczekiwana była liczba. Teraz użyłbyś wyrażenia lambda LINQ, które jest przed tym chronione.
Budowanie interfejsu API LINQ na czystych delegatach nie jest możliwe, ponieważ wymaga połączenia drzew wyrażeń przed ich oceną.
W 2016 r. Większość popularnych języków obsługuje wyrażenia lambda , a C # był jednym z pionierów tej ewolucji wśród głównych języków imperatywnych.
źródło
To chyba najlepsze wyjaśnienie, dlaczego warto używać wyrażeń lambda -> https://youtu.be/j9nj5dTo54Q
Podsumowując, ma to na celu poprawę czytelności kodu, zmniejszenie prawdopodobieństwa błędów przez ponowne użycie zamiast replikacji kodu oraz wykorzystanie optymalizacji za kulisami.
źródło
Największą zaletą wyrażeń lambda i funkcji anonimowych jest fakt, że pozwalają one klientowi (programistowi) biblioteki / frameworka na wstrzykiwanie funkcjonalności za pomocą kodu w danej bibliotece / frameworku (ponieważ jest to LINQ, ASP.NET Core i wiele innych) w sposób, którego zwykłe metody nie mogą. Jednak ich siła nie jest oczywista dla jednego programisty aplikacji, ale dla tego, który tworzy biblioteki, z których później będą korzystać inni, którzy będą chcieli skonfigurować zachowanie kodu biblioteki lub tego, który korzysta z bibliotek. Tak więc kontekstem skutecznego użycia wyrażenia lambda jest użycie / stworzenie biblioteki / frameworka.
Ponieważ opisują kod jednorazowego użycia, nie muszą należeć do klasy, w której doprowadzi to do większej złożoności kodu. Wyobraź sobie, że musisz deklarować klasę z niejasnym skupieniem za każdym razem, gdy chcieliśmy skonfigurować działanie obiektu klasy.
źródło