Farkhodbek Kamolov
Posted on May 30, 2024
Method group haqida qisqacha:
Method group - bu bir xil nomga ega, ammo parametrlari va qaytish turlari(qisqacha sintaksis) bo'yicha farq qilishi mumkin bo'lgan funksiyalar to'plami. Method grouplar odatda delegatlar, hodisalar(event) va LINQ ifodalari bilan bog'liq vaziyatlarda qo'llaniladi. Batafsil malumot -> link.
C# tilidagi method group natural type(tabiy turi) kompilyator tomonidan guruh ichidagi methodlar sintaksiga mos keladigan delegat turiga ishora qiladi. C#-dagi natural type method guruhlarini ishlatish jarayonini soddalashtiradi, delegatlarni talab qiladigan kontekstlarda metod guruhlarini to'g'ridan-to'g'ri va yashirin foydalanishga imkon berish orqali kodni o'qish va samaradorlikni oshiradi. Bu, ayniqsa, LINQ so'rovlari va hodisa(event)larni boshqarish bilan bog'liq stsenariylarda foydalidir. Qisqa qilib aytganda natural type(tabiy tur) kompilyator tomonidan yashirincha delegatga o'giriladi, delegatlar esa o'z vaqtida, o'zining shartlarini qoniqtirgan funksiyani overloadini method groupdan tanlab oladi. Yaniy bu feature(natural type) delegatlarni ochiqchasiga(explecitly) yaratishga xojat qoldirmaydi, kontekstga qarab kompilyator o'zi yaratadi.
Delegatlar qanday ishlashini tushunish uchun kichik bir misol:
Action<string> writeLineString = Console.WriteLine;
writeLineString("Hello, World!");
// output -> Hello, World!
Birinchi qatorda writeLineString
delegati yaratildi, va unga WriteLine
method group o'zlashtirdi. Keyingi qatorda writeLineString
delegatiga string
malumot tipni argument sifatida joylandi, chunki bizning(kontekstda) delegatni sharti, faqat string qabul qiladigon funksiyalarni talab qiladi(Action<string>
). Kompilyatorni o'zi delegatdan foydalanib, WriteLine
guruhidan kerakli overloadni topib ishga tushiradi. Qisqacha delegatlar qanday ishlashi haqidaham tushib oldik
Endi esa C# da natural type tushunchasi kirib kelamagunicha bolgan holat:
var numbers = new[] { 1, 2, 3, 4, 5 };
Func<int, bool> isEvendelegate = IsEven;
var evenNumbers = numbers.Where(isEvendelegate).ToList();
Action<int> writeLineInt = Console.WriteLine;
Console.WriteLine("Even numbers:");
foreach (var num in evenNumbers)
writeLineInt(num);
static bool IsEven(int number) => number % 2 == 0;
Output
Even numbers:
2
4
Func<int, bool>
xuddiAction<string>
kabi ishlaydi, lekin biroz farq qiladi. Func T1 delegatimizga o'zlashtiriladigon method groupga keladigon argument tipi, T2 esa shu methodimiz qaytaradigon malumot turi.Action<T>
esa harqandayvoid
qaytaradigon lekinT
qabul qiladigon method guruhlar uchun ishlatiladi.
Kodda ko'rganimizdek numbers array bor(1dan 5gacha qiymatlari bilan), isEvenDelegati
vakili(delegati) int
type qabul qiluvchi va bool
qaytarubchi method groupni qabul qiladi, bu shartni esa IsEven
methodi qiniqtiradi, shung uchun ushbu metodni delegatimizga o'zlashtirdik. Keyingi qatorda LINQ funksiyalaridan bolmish Where()
metodini delegatimiz unga argument qilib chaqirdik, bu metod esa faqatgina juft sonlardan tashkil topgan arrayni evenNumbers
o'zgaruvchisiga o'zlashtirdi. Etibor qilgan bolsangiz birinchi misolimizdan ozgina farq qiladigon ko'dniham ishlatdik.
Endi esa huddi o'sha kodni faqat natural type bilan modify qilamiz:
var numbers = new[] { 1, 2, 3, 4, 5 };
var evenNumbers = numbers.Where(IsEven).ToList();
Console.WriteLine("Even numbers:");
evenNumbers.ForEach(Console.WriteLine);
bool IsEven(int number) => number % 2 == 0;
Output
Even numbers:
2
4
Ushbu misolimizda ko'rishingiz mumkin hechqanday Func<T1,T2>
yoki Action<T>
delegatlari yoq. Delegatlarni o'rniga tog'ridan to'g'ri method groupni ishlatdik, va natija esa birxil. Yana bir etibor qilishimiz kerak bolgan joyi, Where()
funksiyasi bu safar ToList()
qaytardi, bunday qilishga sabab, ForEach()
metodi faqat list uchun ishlaydi, va bu funksiyaga Console.WriteLine
method groupini delegat ishlatmasdan yubordik.
Aslida bu funksianal "natural type" C# da ~ 10 versiyadan beri bor, lekin o'sha damlardan beri bu optimal emas edi, yaniy kompilyator har bir methodga alohida qarab chiqar edi, hatto bazi funksiyala ochiqchasiga delegat shartini qoniqtirmasaham(boshqa tiplar qabul qilsaham, ko'proq yoki ozroq argumentlar soni bolsaham).
C# 13 da natural typeni ishlash prinsipini to'g'irlandi, endi kompilyator *scope ichidagi tog'ri kelmagan methodlarni tashlab yuboradi.
Agar methodlar generic bolsa yoki yetlicha/ortiqcha argumentlar soni. Agar kerakli method ushbu scopeda topilmasa, qidiruv kelgusi scope ga o'tadi, taqdim etilgan scopelardan birontasida kerakli shartni qoniqtira oladigon methodni topa olmasa, method group natural type-ga ega emas deb hisoblanadi, va compile-time error otadi. Oddiy qilib aytganda, kompilyator endi barcha mumkin bo'lgan methodlarni oldindan ko'rib chiqish o'rniga, har bir scope-ni tekshirganda, qo'llanilmaydigan/keraksiz methodlarni darhol chiqarib tashlash orqali method guruhidan qaysi overloaddan foydalanishni samaraliroq aniqlaydi. Bu esa o'z vaqtida jarayonni tezlashtiradi.
scope deb methodlar implement qilinga kontekstni class, import qilingan namespace larni nazarda tudadi.
Posted on May 30, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.