Umumlashtirish - 1. System. Object sinfi va uning usullari Umumlashtirish

2. Umumlashtirish.
Umumiy turlardan tashqari, .NET ramkasi umumiy turlarni (generics) va umumiy usullarni yaratishni ham qo'llab-quvvatlaydi. Ushbu hodisaning o'ziga xos xususiyatlarini tushunish uchun, avvalo, umumiy tiplar paydo bo'lishidan oldin paydo bo'lgan muammoni ko'rib chiqaylik. Keling, bir misolni ko'rib chiqaylik. Aytaylik, bank hisobini ifodalash uchun sinfni aniqlaymiz. Masalan, u quyidagicha ko'rinishi mumkin:
class Account
{
public int Id { get; set; }
public int Sum { get; set; }
}
Account sinfi ikkita xususiyatni belgilaydi: Id - unikal identifikator va Sum - hisobdagi summa.
Bu erda identifikator raqamli qiymat sifatida ko'rsatilgan, ya'ni bank hisoblari 1, 2, 3, 4 va hokazo qiymatlarga ega bo'ladi. Biroq, identifikator uchun satr qiymatlaridan foydalanish ham keng tarqalgan. Raqamli va satr qiymatlari o'zlarining ijobiy va salbiy tomonlariga ega. Va sinfni yozish paytida biz identifikatorni saqlash uchun nimani tanlash yaxshiroq ekanligini aniq bilmasligimiz mumkin - satr yoki raqam. Yoki, ehtimol, bu sinf ushbu masala bo'yicha o'z fikriga ega bo'lishi mumkin bo'lgan boshqa ishlab chiquvchilar tomonidan qo'llaniladi.
Va birinchi qarashda bu vaziyatdan chiqish uchun Id xossasini object tipidagi xususiyat sifatida belgilashimiz mumkin. object turi universal tip bo'lib, barcha turlar mos ravishda meros bo'lib o'tadi, biz ushbu turdagi xususiyatlarda satrlarni ham, raqamlarni ham saqlashimiz mumkin:
class Account
{
public object Id { get; set; }
public int Sum { get; set; }
}
Keyinchalik bu sinf dasturda bank hisoblarini yaratish uchun ishlatilishi mumkin:
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);
Har bir narsa ajoyib ishlayotganga o'xshaydi, lekin bu yechim juda maqbul emas. Gap shundaki, bu holatda biz ixchamlash (boxing) va ochish (unboxing) kabi hodisalarga duch kelamiz.
Shunday qilib, Id xususiyatiga int tipidagi qiymat tayinlanganda, bu qiymat Object turiga to'planadi:
account1.Id = 2; // int qiymatlarini Object turiga joylashtirish
Ma'lumotlarni int turdagi o'zgaruvchiga qaytarish uchun siz quyidagilarni ochishingiz kerak:
int id1 = (int) account1.Id; // int turiga ochish
boxing qiymat turidagi ob'ektni (masalan, int turi) object turiga aylantirishni o'z ichiga oladi. Paketda umumiy tilning ish vaqti (CLR) qiymatni System.Object tipidagi ob'ektga o'rab oladi va uni boshqariladigan yig'mada saqlaydi. Boshqa tomondan, unboxing object tipidagi ob'ektni qiymat turiga aylantirishni o'z ichiga oladi. Qadoqlash va o'rash unumdorlikni pasaytiradi, chunki tizim kerakli o'zgarishlarni amalga oshirishi kerak.
Bundan tashqari, yana bir muammo bor - turdagi xavfsizlik muammosi. Shunday qilib, agar biz shunday yozsak, biz ish vaqti xatosini olamiz:
Account account2 = new Account { Sum = 4000 };
account2.Id = "4356";
int id2 = (int)account2.Id; // Istisno InvalidCastException
Biz qaysi ob'ekt Id ni ifodalashini bilmasligimiz mumkin va bu holda raqam olishga harakat qilganimizda, biz InvalidCastExceptionga duch kelamiz.
Ushbu muammolar umumiy turlarni (ko'pincha umumiy turlar deb ham ataladi) yo'q qilish uchun mo'ljallangan edi. Umumiy turlar foydalanish uchun ma'lum bir turni belgilash imkonini beradi. Shuning uchun, keling, Account sinfini umumiy deb belgilaymiz:
class Account
{
public T Id { get; set; }
public int Sum { get; set; }
}
|