Funkcje lokalne a lambdy
Wybieraj między funkcjami lokalnymi a lambdami.
Funkcje lokalne a lambdy to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C# Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C# Academy zawiera 4 lekcji w sumie.
Funkcje lokalne a lambdy
Zarówno funkcje lokalne, jak i lambdy pozwalają definiować małe funkcje wewnątrz metody. Mają wiele cech wspólnych, ale różnią się składnią, możliwościami i wydajnością. Wybór właściwego rozwiązania pomaga zachować czytelność i wydajność kodu.
Dwa sposoby zapisywania funkcji pomocniczej
W tym przykładzie ta sama funkcja pomocnicza podnosząca liczbę do kwadratu jest zapisana zarówno jako funkcja lokalna, jak i lambda przypisana do delegata. Oba rozwiązania dają ten sam wynik.
using System;
public class Program
{
public static void Main()
{
int SquareFn(int n) => n * n; // local function
Func<int, int> squareLambda = n => n * n; // lambda
Console.WriteLine(SquareFn(4));
Console.WriteLine(squareLambda(4));
}
}Funkcje lokalne ułatwiają rekurencję
Funkcja lokalna może wywoływać samą siebie po nazwie. Lambda nie może odwoływać się do własnej zmiennej podczas inicjalizacji, dlatego rekurencja z lambdami jest kłopotliwa.
using System;
public class Program
{
public static void Main()
{
// Clean recursion with a local function
int Factorial(int n) => n <= 1 ? 1 : n * Factorial(n - 1);
Console.WriteLine(Factorial(5));
}
}Funkcje lokalne mogą być generyczne
Funkcje lokalne obsługują własne parametry typów. Lambdy nie mogą być generyczne, dlatego w przypadku wielokrotnego użytku typowanych funkcji pomocniczych należy wybrać funkcję lokalną.
using System;
public class Program
{
public static void Main()
{
T First<T>(T[] items) => items[0]; // generic local function
Console.WriteLine(First(new[] { 9, 8, 7 }));
Console.WriteLine(First(new[] { "a", "b" }));
}
}Wydajność: unikanie alokacji delegata
Lambda przypisana do delegata może alokować obiekt delegata, a jeśli przechwytuje zmienne, również domknięcie. Funkcja lokalna wywoływana bezpośrednio pozwala uniknąć obu alokacji, co ma znaczenie w często wykonywanych pętlach.
using System;
public class Program
{
public static void Main()
{
// Direct call, no delegate or closure allocation
static int Add(int a, int b) => a + b;
int total = 0;
for (int i = 0; i < 5; i++) total = Add(total, i);
Console.WriteLine(total);
}
}Parametry out i ref
Funkcje lokalne mogą deklarować parametry out i ref, natomiast lambdy korzystające ze wspólnych delegatów Func/Action nie mogą. Dzięki temu funkcje lokalne naturalnie nadają się do pomocniczych operacji w stylu try-parse.
using System;
public class Program
{
public static void Main()
{
bool TryGetFirstDigit(string s, out int digit)
{
digit = 0;
foreach (var c in s)
if (char.IsDigit(c)) { digit = c - '0'; return true; }
return false;
}
if (TryGetFirstDigit("abc4", out int d))
Console.WriteLine(d);
}
}Lambdy jako argumenty inline
Gdy trzeba przekazać zachowanie bezpośrednio do metody, takiej jak LINQ Where lub Select, lambda jest najbardziej zwięzłą i czytelną opcją.
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
var nums = new List<int> { 1, 2, 3, 4, 5, 6 };
var evens = nums.Where(n => n % 2 == 0).Select(n => n * 10);
Console.WriteLine(string.Join(", ", evens));
}
}Przechwytywanie działa w obu przypadkach
Obie formy mogą przechwytywać zmienne z otaczającego zakresu. Różnica dotyczy głównie składni i kosztu alokacji, a nie tego, czy przechwytywanie jest możliwe.
using System;
public class Program
{
public static void Main()
{
int bonus = 10;
int WithBonusFn(int n) => n + bonus; // captures
Func<int, int> withBonusLambda = n => n + bonus; // captures
Console.WriteLine(WithBonusFn(5));
Console.WriteLine(withBonusLambda(5));
}
}Pewne przypisanie i kolejność
Funkcję lokalną można wywołać przed jej deklaracją w metodzie, natomiast zmienna lambda musi zostać przypisana przed użyciem. Dzięki temu funkcje lokalne można umieszczać w bardziej elastyczny sposób.
using System;
public class Program
{
public static void Main()
{
Console.WriteLine(Triple(4)); // allowed before declaration
int Triple(int n) => n * 3;
}
}Wybór między nimi
Funkcji lokalnej należy używać w przypadku nazwanych, wielokrotnego użytku, rekurencyjnych, generycznych lub często wykonywanych pomocników. Lambdy należy używać w przypadku krótkiego zachowania przekazywanego bezpośrednio do innej metody. Obie konstrukcje są narzędziami — należy wybrać tę właściwą do danego celu.
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
static bool IsPrime(int n)
{
if (n < 2) return false;
for (int i = 2; i * i <= n; i++)
if (n % i == 0) return false;
return true;
}
var primes = Enumerable.Range(2, 20).Where(IsPrime);
Console.WriteLine(string.Join(", ", primes));
}
}Spróbuj samodzielnie
Należy użyć rekurencyjnej funkcji lokalnej dla głównej logiki oraz lambdy dla projekcji LINQ wykonywanej inline, tak aby każda konstrukcja mogła robić to, w czym sprawdza się najlepiej.
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
// Local function: recursive, named, reusable
static int DigitCount(int n) => Math.Abs(n) < 10 ? 1 : 1 + DigitCount(n / 10);
var nums = new List<int> { 5, 42, 1000, 7, 88 };
// Lambda: concise inline projection
var report = nums.Select(n => n + " has " + DigitCount(n) + " digits");
foreach (var line in report) Console.WriteLine(line);
}
}Szybkie sprawdzenie
Należy porównać obie konstrukcje.
Podsumowanie
Funkcje lokalne i lambdy mają część wspólnych zastosowań, ale różnią się w kilku istotnych kwestiach.
- Funkcje lokalne mogą być rekurencyjne i generyczne oraz mogą używać
out/ref. - Wywoływane bezpośrednio, nie wymagają alokowania delegata ani domknięcia.
- Lambdy są najbardziej zwięzłe jako argumenty inline metod takich jak LINQ.
- Należy wybierać zgodnie z przeznaczeniem: nazwany pomocnik wielokrotnego użytku albo krótkie zachowanie inline.
Często zadawane pytania
Czy lekcja „Funkcje lokalne a lambdy” jest bezpłatna?
Tak — pełny tekst „Funkcje lokalne a lambdy” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C# Academy, przejdź na CoddyKit PRO. Kurs C# Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Funkcje lokalne a lambdy”?
Wybieraj między funkcjami lokalnymi a lambdami. Ćwiczysz C# Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć C# Academy?
Nie wymagamy żadnego doświadczenia. C# Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Funkcje lokalne a lambdy”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji C# Academy?
Tak. Każda lekcja C# Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Deklarowanie funkcji lokalnych
- Domknięcia i przechwytywane zmienne
- Statyczne funkcje lokalne
- Funkcje lokalne a lambdy