Umumlashtirish


Download 19.27 Kb.
Sana21.11.2023
Hajmi19.27 Kb.
#1792371
Bog'liq
UMUMLASHTIRISH(C# va Net)




UMUMLASHTIRISH

Bu mavzu C# ning eng murakkab va samarali vositalaridan biri bo‘lgan umumlashuvlarga bag‘ishlangan. Umumlashuvlar dastlabki 1.0 versiyasiga kirmagan va faqatgina 2.0 versiyasida paydo boʻlgan, ammo endi ular C # tilining ajralmas qismi hisoblanadi. Umumlashuvlarni joriy etish C # xususiyatini tubdan o‘zgartirdi, deb bo‘lmaydi. Ushbu yangilik mazkur til sintaksisining yangi elementining yaratilishini bildirmadi, balki sinflar kutubxonasiga ko‘plab o‘zgartirishlar va yangilashlar kiritish uchun yangi imkoniyatlar ochdi. Umumlashuvlar joriy etilgandan keyin bir necha yil o‘tgan bo‘lsa da, ushbu muhim qadamning oqibatlari C # ni dasturlashtirish tili sifatida rivojlantirishga hali ham ta’sir ko‘rsatmoqda.


Til vositasi sifatidagi umumlashlar o‘ta muhim, chunki ular turlarning xavfsizligiga rioya qilgan holda turli ma’lumotlarni qayta ishlash uchun sinf, tuzilma, interfeys, usul va delegatlarni yaratish imkonini beradi. Ma’lumki, ko‘plab algoritmlar ular qo‘llanilayotgan ma’lumotlar turidan qat’i nazar, o‘z logikasi bo'yicha o‘xshash hisoblanadi. Masalan, navbatning int, string, object ko‘rinishidagi elementlarni saqlash uchun yoki foydalanuvchi tomonidan belgilanadigan sinf uchun mo‘ljallanganidan bo'lishidan qat’iy nazar navbatni qo‘llab-quvvatlaydigan mexanizm bir xil bo‘ladi. Turli turdagi ma’lumotlarni qayta ishlash uchun umumlashlar yaratilmasdan oldin bir xil algoritmning turli variantlarini yaratish lozim bo‘lgan. Umumlashuvlar tufayli esa dastlab ma’lumotlarning aniq turidan qat’i nazar yagona echimni ishlab chiqish, so‘ngra uni biron-bir qo‘shimcha harakatlarsiz turli turdagi ma’lumotlarni qayta ishlashga qo‘llash mumkin.
Mazkur mavzuda umumlashtirishlarni qo‘llash sintaksisi, nazariysi va amaliyoti tasvirlanadi, shuningdek, ilgari murakkab holatlarda namunaviy xavfsizlikni qanday ta’minlashi ko‘rsatiladi.
Umumlashtirish nima?
Umumlashtirish atamasi, aslida, parametrlashtirilgan turni anglatadi. Parametrlashtirilgan turlarning alohida o‘rni shundan iborat bo‘lib, ular ishlanayotgan ma’lumotlar parametr shaklida ko‘rsatiladigan sinf, tuzilma, interfeys, usul va delegatlarni yaratish imkonini beradi. Ma’lumotlar yordamida, masalan, yagona sinfni yaratish mumkin bo‘lib, u turli ma’lumotlarni ishlash uchun avtomatik ravishda yaratiladi. Ma’lumotlarning parametrlarini amalga oshiradigan sinf, tuzilma, interfeys, usul yoki delegat, masalan, umumlashtirilgan sinf yoki umumlashtirilgan usul sifatida umumlashtirilgan hisoblanadi.
Alohida ta’kidlash kerakki, C # da har doim object turi bilan umumlashtirilgan kodni yaratish imkoniyati bo‘lgan. Object sinfi esa boshqa barcha sinflar uchun asosiy boʻlganligi sababli, object tipidagi havola orqali har qanday turdagi obyektga murojaat qilish mumkin. Shu tariqa, turli turdagi ob’ektlarni amalga oshirish uchun umumlashtirilgan kodlar ko‘rsatilmoqda.
Lekin bunday kodda namunaviy xavfsizlikka rioya etish qiyin bo‘ldi, chunki object turini ma’lumotlarning aniq turiga aylantirish uchun turlarni keltirish zarur bo‘lgan. Bu turlarni keltirish amali noto‘g‘ri bajarilishi sababli xatolarsodir bo'ladi. Ushbu qiyinchilikni bartaraf etish tur xavfsizligini ta’minlash orqali umumlashtirish bilan hal qilindi. Bundan tashqari, umumlashtirishlar butun jarayonni soddalashtiradi, chunki ob’ektni yoki ishlanayotgan ma’lumotlarning boshqa turini o‘zgartirish uchun turlarni keltirishni bajarish zarurligini hal etadi. Shu tariqa, umumlashuvlar koddan qaytadan foydalanish imkoniyatlarini kengaytiradi va buni ishonchli va oson amalga oshirish imkonini beradi.
Oddiy freymvork turlaridan tashqari .NET umumlashtirilgan turlarni ham qoʻllab-quvvatlaydi. Mazkur holatning xususiyatini aniqlash uchun avvalo umumlashtirilgan turlar ko‘rilishidan oldin kelib chiqishi mumkin bo‘lgan muammolarni ko‘rib chiqamiz. Misolni ko‘rib chiqamiz. Masalan, biz bank hisobvaraqini taqdim etish uchun sinfni belgilaymiz. Masalan, u quyidagicha koʻrinishi mumkin edi:
class Account
{
public int Id { get; set; }
public int Sum { get; set; }
}
Account sinfi ikkita xususiyatni belgilaydi:

Bu erda identifikator sonli qiymati sifatida belgilangan, bank hisob varaqlari 1, 2, 3, 4 va shu kabi qiymatlarga ega bo‘ladi. Biroq, ko‘p o‘rinlarda identifikator uchun satr qiymatlaridan ham foydalaniladi. Sonli va satr iymatlarni ham o‘z plyustlari va minuslari mavjud. Sinfni yozish vaqtida aniqlash uchun nima tanlash yaxshi ekanini aniq bilmaslik mumkin. Yoki bu sinf mazkur muammo bo‘yicha o‘z fikriga ega bo‘lgan boshqa ishlab chiqaruvchilar tomonidan foydalanishi mumkin.


Bunday vaziyatdan chiqish uchun biz Id xossasini object xos xususiyati sifatida belgilab olishimiz mumkin. Chunki object turi universal turdir, undan barcha turlar meros qilinadi, shuning uchun biz bunday turdagi xususiyatlarda satrlarni ham, sonlarni ham saqlab qolishimiz mumkin:


class Account


{
public object Id { get; set; }
public int Sum { get; set; }
}
Shundan so‘ng ushbu sinfdan quyidagi dasturda bank hisobvaraqlarini yaratish uchun foydalanish mumkin bo‘ldi:

Account account1 = new Account { Sum = 5000 };


Account account2 = new Account { Sum = 4000 };
account1.Id = 2;
account2.Id = "4356";
int id1 = (int)account1.Id;
string id2 = (string)account2.Id;
Console.WriteLine(id1);
Console.WriteLine(id2);
Barchasi yaxshi faoliyat ko‘rsatayotgani ko‘rsatilmoqda, lekin bunday echim unchalik optimal emas. Gap shunday bo‘lsa, bunday holatda biz joylash (boxing) va ochish (unboxing) kabi holatlarga tush kelamiz.
Jumladan, int ko‘rinishidagi ma’lumot Id xususiyatiga o‘rnatilganda, ushbu qiymatni Object turiga joylash mumkin:
account1.Id = 2;// Object turiga int qiymatini joylash
Ma’lumotlarni int turidagi o‘zgaruvchiga qaytarish uchun quyidagi ochishni amalga oshirish kerak:

int id1 = (int) account1.Id ;//int turiga ochish


Joylash(boxing) muhim turdagi ob’ektni (masalan, int turi) objekt turiga aylantirishni ko‘zda tutadi. Buyruqda umuiylik muhit CLR Sistem.Object ko‘rinishidagi ob’ektga qo‘llanadi va uni boshqariladigan yig‘inda (xipda-kuchada) saqlaydi. Ochish (unboxing), aksincha, object tipidagi ob’ektni muhim turga aylantirishni ko‘zda tutadi. Joylash va ochish dasturning samaradorligi kamayishiga olib keladi, chunki tizimga zarur o‘zgarishlarni amalga oshirish zarur.
Bundan tashqari, boshqa muammo – turlarning xavfsizligi muammosi mavjud. Jumladan, agar quyidagi tarzda yozsak dasturni bajarish vaqtida muvaffaqiyatga ega bo‘lmaymiz, :

Account account2 = new Account { Sum = 4000 };


account2.Id = "4356";
int id2 = (int) account2.Id ;//istisno InvalidCastException
Biz Id nisbatan qanday ob’ektni taqdim etayotganini bilmasligimiz mumkin va bu holatda sonni olishga InvalidCastException istisno holot sodir bo'ladi.

Ushbu muammolar umumlashtirilgan turlarni bartaraf etishga mo‘ljallangan. Umumlashtirilgan turlar foydalaniladigan aniq turni ko‘rsatish imkonini beradi. Shuning uchun Account sinfini umumlashtirilgan variantini quyidagicha yozamiz:


class Account


{
public T Id { get; set; }
public int Sum { get; set; }
}
Sinfning umumlashtirilgan ekanligini, burchak qavslaridagi T turining esa shu sinf tomonidan ishlatilishini koʻrsatadi. Aynan T harfidan foydalanish zarur emas, bu har qanday boshqa harf yoki simvollsr to‘plami ham bo‘lishi mumkin. Bu qanday turda bo‘lishi bizga ma’lum emas, bu har qanday turdagi bo‘lishi mumkin. Shuning uchun burchakdagi T parametri hali universal parametr deb ataladi, chunki uning oʻrniga istalgan turni qoʻyish mumkin.
Masalan, T parametri o‘rniga int ob’ektidan foydalanish mumkin. Bu ham string ob’ekti yoki hech qanday boshqa sinf yoki tuzilma bo‘lishi mumkin:

Account account1 = new Account { Sum = 5000 };


Account account2 = new Account { Sum = 4000 };
account1.Id = 2 ;//buyruqlash kerak emas
account2.Id = "4356";
int id1 = account1.Id ;//ochish kerak emas
string id2 = account2.Id;
Console.WriteLine(id1);
Console.WriteLine(id2);
Account sinfi umumlashtirilganligi sababli, turning nomini belgilashda burchak qavslarda universal parametri o’rniga ishlatiladigan turni ko’rsatish kerak.

Account account1 = new Account { Sum = 5000 };


Account account2 = new Account { Sum = 4000 };
Shuning uchun birinchi account1 obyektda Id xossasida int, account2 obʼyektda esa string turi mavjud.

Boshqa turdagi o‘zgaruvchiga Id xossasi qiymatini o‘rnatib bo‘lmaydi:


Account account2 = new Account { Sum = 4000 };


account2.Id = "4356";
int id1 = account2.Id ;//kompilyatsiya xatosi
Shu bilan tur xavfsizligi muammolari hal bo'ladi. Shu tariqa, sinfning umumlashtirilgan variantidan foydalanib, bajarish vaqtini va salohiyatli xatolar sonini kamaytiramiz.
Standart qiymatlar
Baʼzan universal parametrlar o‘zgaruvchilariga boshlang‘ich qiymat, shu jumladan null qiymatini ham o'zlashtirish zaruriyati bo'lishi mumkin. Lekin biz uni to‘g‘ridan-to‘g‘ri o'zlashtira olmaymiz:

T id = null;


Bu holatda biz default (T) operatoridan foydalanishimiz kerak. U holda havola turlariga null qiymati, qiymatlar turlariga esa 0 o'zlashtiriladi:

class Account


{
T id = default(T);
}
Umumlashtirilgan sinflarning statik maydonlari
Umumlashtirilgan sinfni turlashtirishda o‘z statik a’zolari to‘plami yaratiladi. Masalan, Account sinfida quyidagi statik maydon belgilangan:

class Account


{
public static T session;

public T Id { get; set; }


public int Sum { get; set; }
}
Endilikda sinfni ikki xil int va string bilan turlashtiramiz:

Account account1 = new Account { Sum = 5000 };


Account.session = 5436;

Account account2 = new Account { Sum = 4000 };


Account.session = "45245";

Console.WriteLine(Account.session); // 5436


Console.WriteLine(Account.session); // 45245
Natijada Account < string > va Account < int > uchun o’zining session o’zgaruvchisi yaratiladi.

Bir nechta universal parametrlardan foydalanish


Umumlashuvlar bir vaqtning oʻzida bir nechta universal parametrlardan foydalanishi mumkin:

class Transaction


{
public U FromAccount { get; set; }//kaysi hisobvaraqdan o‘tkazish
public U ToAccount { get; set; }//qanday hisobvaraqga o‘tkazish
public V Code { get; set; }//amal kodi
public int Sum { get; set; }//o‘tkazish summasi
}
Bu erda Transaction sinfi ikkita universal parametrdan foydalanadi. Mazkur sinfdan foydalanishimiz:

Account acc1 = new Account { Id = 1857, Sum = 4500 };


Account acc2 = new Account { Id = 3453, Sum = 5000 };

Transaction, string> transaction1 = new Transaction, string>


{
FromAccount = acc1,
ToAccount = acc2,
Code = "45478758",
Sum = 900
};
Bu yerda Transaction obyekti Account < int > va string tiplari bilan tiplashtiriladi. Yaʼni U universal parametri sifatida Account < int > sinfidan, V parametri uchun esa string turidan foydalaniladi. Bunda, ta’kidlanganidek, Transaction tiplanadigan sinfning o’zi umumlashtirilgan.
Umumlashtirilgan usullar
Umumlashtirilgan sinflardan tashqari umumlashtirilgan usullarni yaratish mumkin, ular ham universal parametrlardan foydalanadi. Masalan:
class Program
{
private static void Main(string[] args)
{
int x = 7;
int y = 25;
Swap < int >
Console.WriteLine($"x={x} y={y}"); // x=25 y=7

string s1 = "hello";


string s2 = "bye";
Swap < string >;
Console.WriteLine($"s1={s1} s2={s2}"); // s1=bye s2=hello

Console.Read();


}
public static void Swap (ref T x, ref T y)
{
T temp = x;
x = y;
y = temp;
}
}
Bu erda havola bo‘yicha parametrlarni qabul qiladigan va ularning qiymatlarini o‘zgartiradigan Swap usuli belgilangan. Bunda mazkur holda ushbu parametrlarning qanday turdagi bo‘lishi muhim emas.


Main usulida biz Swap usulini chaqiramiz, uni muayyan turda tiplashtiramiz va unga ayrim qiymatlarni uzatamiz.

Download 19.27 Kb.

Do'stlaringiz bilan baham:




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling