DEV Community

Farkhodbek Kamolov
Farkhodbek Kamolov

Posted on

Natural type of Method group

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!
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

Output

Even numbers:
2
4
Enter fullscreen mode Exit fullscreen mode

Func<int, bool> xuddi Action<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 harqanday void qaytaradigon lekin T 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;
Enter fullscreen mode Exit fullscreen mode

Output

Even numbers:
2
4
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)