Patrzę na nowe implementacje w C # 7.0 i wydaje mi się interesujące, że zaimplementowały funkcje lokalne, ale nie mogę sobie wyobrazić scenariusza, w którym funkcja lokalna byłaby preferowana nad wyrażeniem lambda i jaka jest różnica między nimi.
Rozumiem, że lambdy są anonymous
funkcjami, podczas gdy funkcje lokalne nie są, ale nie mogę rozgryźć rzeczywistego scenariusza, w którym funkcja lokalna ma przewagę nad wyrażeniami lambda
Każdy przykład byłby bardzo mile widziany. Dzięki.
Odpowiedzi:
Wyjaśnił to Mads Torgersen w C # Design Meeting Notes, gdzie po raz pierwszy omówiono funkcje lokalne :
Aby jeszcze bardziej go rozwinąć, zalety to:
Występ.
Podczas tworzenia lambdy należy utworzyć delegata, co w tym przypadku jest niepotrzebną alokacją. Funkcje lokalne to tak naprawdę tylko funkcje, nie są potrzebni żadne delegaty.
Ponadto funkcje lokalne są bardziej wydajne przy przechwytywaniu zmiennych lokalnych: lambdy zwykle przechwytują zmienne do klasy, podczas gdy funkcje lokalne mogą używać struktury (przekazywanej za pomocą
ref
), co ponownie unika alokacji.Oznacza to również, że wywoływanie funkcji lokalnych jest tańsze i można je wbudować, co może jeszcze bardziej zwiększyć wydajność.
Funkcje lokalne mogą być rekurencyjne.
Lambdy mogą być również rekurencyjne, ale wymaga niezręcznego kodu, w którym najpierw należy przypisać
null
do zmiennej delegata, a następnie lambda. Funkcje lokalne mogą naturalnie być rekurencyjne (w tym rekurencyjne wzajemnie).Funkcje lokalne mogą być ogólne.
Lambdy nie mogą być generyczne, ponieważ muszą być przypisane do zmiennej o konkretnym typie (ten typ może używać zmiennych ogólnych z zewnętrznego zakresu, ale to nie to samo).
Funkcje lokalne mogą być implementowane jako iterator.
Lambdy nie mogą używać słowa kluczowego
yield return
(iyield break
) do implementacjiIEnumerable<T>
funkcji -returning. Funkcje lokalne mogą.Funkcje lokalne wyglądają lepiej.
Nie jest to wspomniane w powyższym cytacie i może to być tylko moje osobiste uprzedzenie, ale myślę, że normalna składnia funkcji wygląda lepiej niż przypisanie lambda do zmiennej delegowanej. Funkcje lokalne są również bardziej zwięzłe.
Porównać:
źródło
Func<int, int, int> f = (x, y) => x + y; f(arg1:1, arg2:1);
.object
. Zatem lambdy mogłyby używać struktury, ale musiałaby być opakowana, więc nadal miałbyś tę dodatkową alokację.Oprócz świetnej odpowiedzi Svicka, funkcje lokalne mają jeszcze jedną zaletę:
można je zdefiniować w dowolnym miejscu funkcji, nawet po
return
instrukcji.źródło
#region Helpers
dolnej części funkcji, aby uniknąć bałaganu w tej funkcji, a zwłaszcza uniknąć bałaganu w głównej klasie.Jeśli również zastanawiasz się, jak przetestować funkcję lokalną, powinieneś sprawdzić JustMock, ponieważ ma on odpowiednią funkcjonalność. Oto prosty przykład klasy, który zostanie przetestowany:
A oto jak wygląda test:
Oto link do dokumentacji JustMock .
Zrzeczenie się. Jestem jednym z deweloperów odpowiedzialnych za JustMock .
źródło
.DoNothing().OccursOnce();
A później potwierdź, że wywołanie zostało wykonane przez wywołanieMock.Assert(foo);
metody. Jeśli jesteś zainteresowany, w jaki sposób obsługiwane są inne scenariusze, możesz przeczytać nasz artykuł pomocy dotyczący potwierdzania występowania .Używam funkcji inline, aby uniknąć presji na zbieranie śmieci, szczególnie w przypadku dłuższych metod. Powiedzmy, że chciałbyś otrzymać dane z 2 lat lub dane rynkowe dla danego symbolu giełdowego. W razie potrzeby można również spakować wiele funkcji i logiki biznesowej.
wystarczy otworzyć połączenie przez gniazdo z serwerem i przejrzeć dane wiążące zdarzenie ze zdarzeniem. Można o tym myśleć w ten sam sposób, jak o projektowaniu klasy, tylko że nie pisze się wszędzie metod pomocniczych, które tak naprawdę działają tylko dla jednej funkcjonalności. poniżej znajduje się próbka tego, jak to może wyglądać. Zwróć uwagę, że używam zmiennych, a metody „pomocnicze” znajdują się poniżej. W Wreszcie ładnie usuwam programy obsługi zdarzeń, jeśli moja klasa Exchange byłaby zewnętrzna / wstrzyknięta, nie zarejestrowałbym żadnego oczekującego programu obsługi zdarzeń
Możesz zobaczyć zalety, jak wspomniano poniżej, tutaj możesz zobaczyć przykładową implementację. Mam nadzieję, że pomoże to wyjaśnić korzyści.
źródło