1. Giriş
Bəlkə bilmirsiniz, amma müsahibələrdə tez-tez verilən sevimli suallardan biri — “Lambda-ifadələr haqqında nə bilirsiniz?”. Niyə soruşurlar? Çünki bu, C#-də çox rahat və "trend" bir şeydir, kodu daha qısa və ifadəli yazmağa kömək edir. Əgər anonymous metodlar əllə məktub yazmağa bənzəyirsə, onda lambda-ifadələr mesajı messencerlə göndərməyə bənzəyir: sürətli, kompakt və bəzən hətta emoji ilə (demək olar).
Lambda-ifadələr C#-ə 3.0 versiyası ilə gəldi və o vaxtdan bəri hər yerdə istifadə olunur: LINQ, event handler-lərdə, thread-lərdə, collections və hətta .NET üzərindəki AI kitabxanalarında.
Lambda-ifadə — kod daxilində, "yerində", isimsiz bir metod elan etməyin yolu, super-qısa və aydın. Əsas sintaksis həmişə belə görünür:
(parametrlər) => ifadə_və_yaxud_block_kod
Bu "ox" => lambda-operator və ya "arrow" adlanır.
Kiçik analogiya
Resept yazmağınızı xatırlayın: “Almanı götür, doğra, kasaya qoy”.
C#-də bu belə olardı:
(alma) => dohra(alma)
2. Anonymous metodu lambdaya çevirmək
Tutaq ki, bizim delegatımız var:
delegate int SquareDelegate(int x);
Anonymous metod belə görünərdi:
SquareDelegate sq = delegate(int x) {
return x * x;
};
İndi eyni şeyi lambda-ifadə ilə göstərək:
SquareDelegate sq = (int x) => { return x * x; };
Amma C# tipləri çıxara bilir, ona görə daha qısaldılmış yazmaq olar:
SquareDelegate sq = x => x * x;
Möhtəşəm kompaktlıq!
"Adi" metod və anonymous funksiyaya müqayisə
| Yol | Elan | Harada istifadə etmək olar | Eksiler |
|---|---|---|---|
| Adlandırılmış metod | Class-da | Hər yerdə | Ad lazım, daha çox kod |
| Anonymous metod | Kod daxilində | Yalnız delegatlarla | Daha kobud sintaksis |
| Lambda-ifadə | Kod daxilində | Delegatlarla hər yerdə | Bəzən tip qeyri-müəyyən ola bilər |
3. Lambda-ifadənin sintaksisi: variasiyalar
Parametrlər
Parametrsiz:
Action hello = () => Console.WriteLine("Salam, dünya!");
Bir parametr (mötərizəni yazmaya bilərsiniz):
Func<int, int> inc = x => x + 1;
Bir neçə parametr (mötərizələr lazımdır):
Func<int, int, int> sum = (a, b) => a + b;
Lambda-nın gövdəsi
Bir ifadə — mötərizələr və return olmadan:
x => x * x
Code block — süslü mötərizələr, return tələb oluna bilər:
(x, y) =>
{
int z = x + y;
return z * z;
}
Parametr tipləri
Çox vaxt tipi göstərməyə ehtiyac yoxdur — compiler özü çıxarır. Amma göstərmək istəsəniz, olar:
(x, y) => x + y // Compiler tipləri özü çıxarır.
(int x, int y) => x + y // Açıqca yaza bilərsiniz.
4. Nüanslar və daha real nümunələr
Collections ilə istifadə
Bizim tədris mini-app-ı xatırlayın (məsələn, istifadəçilər siyahısı)? Tutaq ki, rəqəmlər massivimiz var:
int[] numbers = { 1, 2, 3, 4, 5 };
Yalnız cüt ədədləri seçmək lazımdır:
var evenNumbers = numbers.Where(n => n % 2 == 0);
Burada Where LINQ extension method-dur, şərt isə bizim lambda-filter-imizdir.
Metodun parametrinə ötürmə
Tutaq ki, delegat-tipli metodumuz var:
public delegate bool Filter(int number);
public static int[] FilterNumbers(int[] data, Filter predicate)
{
var result = new List<int>();
foreach (var n in data)
if (predicate(n))
result.Add(n);
return result.ToArray();
}
İndi lambda-ifadəni ötürürük:
int[] evens = FilterNumbers(numbers, n => n % 2 == 0);
Hadisə handler-i kimi lambda
button.Click += (sender, args) => Console.WriteLine("Düymə basıldı!");
5. Lambda-ifadələr və standart generic delegatlar
Lambda-ları Func<>, Action<> və Predicate<> olmadan təsəvvür etmək çətindir. Bunlar xüsusi delegat tipləridir:
- Action — heç nə qaytarmır.
- Func — dəyər qaytarır.
- Predicate — bool qaytarır, adətən filter üçün istifadə olunur.
Action nümunəsi:
Action<string> log = message => Console.WriteLine(message);
log("Bu mesaj lambda vasitəsilədir!");
Func nümunəsi:
Func<int, int, int> multiply = (a, b) => a * b;
int product = multiply(3, 5); // 15
Predicate nümunəsi:
Predicate<int> isNegative = n => n < 0;
bool test = isNegative(-7); // true
6. Bir neçə ifadəli lambda-lar: nə vaxt block lazımdır
Əgər lambda bir neçə əməliyyat yerinə yetirməlidirsə, süslü mötərizələrdən və açıq return-dan istifadə edin:
Func<int, int, string> describeSum = (a, b) =>
{
int sum = a + b;
return $"Cəm: {sum}";
};
return olmadan compiler narahat olacaq (amma çox vaxt niyə deməyəcək — sadəcə "bütün yollar dəyər qaytarmır" yazacaq).
7. void qaytarışı: Action
Lambda heç nə qaytarmırsa, Action-dan istifadə edin:
Action greet = () => Console.WriteLine("Gülün — kod kompilyasiya olunur!");
Lambda istənilən sayda ifadə ehtiva edə bilər:
Action<int> printSquare = x =>
{
int sq = x * x;
Console.WriteLine($"Ədədin {x} kvadratı {sq}-dır");
};
8. Məhdudiyyətlər və tipik səhvlər
Bəzən lambda-nı çox sərbəst yazmaq istəyərlər, amma compiler hər zaman razı olmaya bilər.
Xaricdə tutulmuş (captured) dəyişən ilə eyni adda yeni dəyişən elan etmək olmaz.
Tipə diqqət edin: əgər delegatın imzası ilə lambda uyğun gəlməzsə — səhv alınacaq.
Əgər delegat dəyər qaytarmalıdırsa, qaytarış mütləqdir.
Mürəkkəb lambda-larda süslü mötərizələri unutmayın. Bir ifadədirsə — mötərizə və return yoxdur. Bir neçə əməliyyatdırsa — mötərizə və return tələb olunur.
GO TO FULL VERSION