Ienumerable va ienumerator interfeysi metodlarini sinfda qayta aniqlash
Download 31.88 Kb.
|
IEnumerable va IEnumerator interfeysi metodlarini sinfda qayta aniqlash
IEnumerable va IEnumerator interfeysi metodlarini sinfda qayta aniqlash Ko‘rganimizdek, ko‘plab kollektsiyalar uchun asosiy masala IEnumerable va IEnumerator interfeyslarini amalga oshirishdir. Shunday amalga oshirish natijasida biz foreach tsiklidagi ob’ektlarni tanlab olishimiz mumkin: foreach (var item in ro‘yxatga olingan _ ob’ekt) { }
IEnumerable interfeysi boshqa interfeysga havola qaytaruvchi usulga ega: public interface IEnumerable { IEnumerator GetEnumerator(); } IEnumerator interfeysi esa konteynerdagi ichki ob’ektlarni tanlash faoliyatini belgilaydi: public interface IEnumerator { bool MoveNext () ;//elementlar konteynerida bir pozitsiyaga oldiga ko‘chirish object Current {get; }//joriy element void Reset () ;//konteyner boshiga ko‘chirish } MoveNext () usuli ko‘rsatkichni joriy elementga keyingi pozitsiyaga o‘tkazadi. Agar izchil hali yakunlanmagan bo‘lsa, shuningdek, true. Agar izchil tugagan bo‘lsa, false qaytadi. Current xossasi ob’ektni ko‘rsatkich ko‘rsatadigan qatorlikda qaytaradi. Reset () usuli pozitsiya ko‘rsatkichini boshlang‘ich holatga tashlaydi. Ko‘rsatkichni ko‘chirish va elementlarni olish interfeysni amalga oshirishga nisbatan bog‘liq. Turli amalga oshirishlarda logika turli tarzda qurilishi mumkin. Masalan, foreach tsiklidan foydalanishsiz, kollektsiyani IEnumerator interfeysi yordamida tanlayman: using System; using System.Collections; namespace HelloApp { class Program { { static void Main(string[] args) { int[] numbers = { 0, 2, 4, 6, 8, 10 }; IEnumerator ie = numbers.GetEnumerator(); //IEnumerator olamiz while (ie.MoveNext ()//false qaytarilganga qadar { int item = (int) ie. Current ;//elementni joriy pozitsiyaga olamiz Console.WriteLine (item); } ie. Reset () ;//ko‘rsatkichni ko‘rsatkichning boshiga tashlayman Console.Read(); } } } IEnomerable va IEnomeratorni amalga oshirish Quyidagilar misolida IEnumerable-ni oddiy amalga oshirishni ko‘rib chiqamiz: using System; using System.Collections; namespace HelloApp { class Week : IEnumerable { string[] days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; public IEnumerator GetEnumerator() { return days. GetEnumerator(); } } class Program { static void Main(string[] args) { Week week = new Week(); foreach(var day in week) { Console.WriteLine(day); } Console.Read(); } } } Ushbu holatda hafta namoyish etadigan va haftaning barcha kunlarini saqlaydigan Week sinfi IEnumerable interfeysini amalga oshiradi. Biroq, bu holatda biz bugungi kunda to‘g‘ri ishladik – IEnumeratorni amalga oshirish o‘rniga, oddiy IEnumerator ob’ektini massiv uchun qaytarmoqdamiz. public IEnumerator GetEnumerator() { return days. GetEnumerator(); } Shu natijada haftaning barcha kunlarini foreach tsiklida o‘tkazishimiz mumkin. Shu bilan birga, kollektsiyani foreach orqali tanlash uchun IEnumerable interfeysini amalga oshirish zarur emas. Sinfda IEnomerator ob’ektini qaytaradigan ommaviy GetEnumerator usulini aniqlash etarli. Masalan: class Week { string[] days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; public IEnumerator GetEnumerator() { return days. GetEnumerator(); } } Biroq, buning uchun oddiy bo‘ldi – biz oddiy tayyor bo‘lgan ko‘rsatkichdan foydalanamiz. Biroq, ob’ektlarni tanlash bo‘yicha o‘z logikasini o‘rnatish zarur bo‘lishi mumkin. Buning uchun IEnumerator interfeysini amalga oshiramiz: using System; using System.Collections; namespace HelloApp { class WeekEnumerator : IEnumerator { string[] days; int position = -1; public WeekEnumerator(string[] days) { this.days = days; } public object Current { get { if (position == -1 || position >= days. Length) throw new InvalidOperationException(); return days[position]; } } public bool MoveNext() { if(position < days. Length - 1) { position++; return true; } else return false; } public void Reset() { position = -1; } } class Week { string[] days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; public IEnumerator GetEnumerator() { return new WeekEnumerator(days); } } class Program { static void Main(string[] args) { Week week = new Week(); foreach(var day in week) { Console.WriteLine(day); } Console.Read(); } } } Endilikda Week sinfi o‘rnatilgan ro‘yxatdan emas, balki IEnumeratordan foydalanadi. Ro‘yxatni amalga oshirishda - ko‘rsatkichni elementga ko‘chirishda asosiy vaqt. Joriy o‘rinni saqlash uchun WeekEnumerator sinfida o‘zgaruvchi position belgilangan. E’tiborga olish kerakki, eng boshida (asosiy holatda) ko‘rsatkich birinchi element oldida shartli ravishda pozitsiyasini ko‘rsatishi kerak. Foreach tsikli ishlab chiqarilganda, ushbu tsikl avvalo MoveNext usulini undiradi va ko‘rsatkichni faqat keyinchalik Current kasbiga murojaat qiladi. IEnumerable va IEnumeratorni amalga oshirish Quyidagilar misolida IEnumerable-ni oddiy amalga oshirishni ko‘rib chiqamiz: using System; using System.Collections; namespace HelloApp { class Week : IEnumerable { string[] days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; public IEnumerator GetEnumerator() { return days. GetEnumerator(); } } class Program { static void Main(string[] args) { Week week = new Week(); foreach(var day in week) { Console.WriteLine(day); } Console.Read(); } } } Ushbu holatda hafta namoyish etadigan va haftaning barcha kunlarini saqlaydigan Week sinfi IEnumerable interfeysini amalga oshiradi. Biroq, bu holatda biz bugungi kunda to‘g‘ri ishladik – IEnumeratorni amalga oshirish o‘rniga, oddiy IEnumerator ob’ektini massiv uchun qaytarmoqdamiz. public IEnumerator GetEnumerator() { return days. GetEnumerator(); } Shu natijada haftaning barcha kunlarini foreach tsiklida o‘tkazishimiz mumkin. Shu bilan birga, kollektsiyani foreach orqali tanlash uchun IEnumerable interfeysini amalga oshirish zarur emas. Sinfda IEnomerator ob’ektini qaytaradigan ommaviy GetEnumerator usulini aniqlash etarli. Masalan: class Week { string[] days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; public IEnumerator GetEnumerator() { return days. GetEnumerator(); } } Biroq, buning uchun oddiy bo‘ldi – biz oddiy tayyor bo‘lgan ko‘rsatkichdan foydalanamiz. Biroq, ob’ektlarni tanlash bo‘yicha o‘z logikasini o‘rnatish zarur bo‘lishi mumkin. Buning uchun IEnomerator interfeysini amalga oshiramiz: using System; using System.Collections; namespace HelloApp { class WeekEnumerator : IEnumerator { string[] days; int position = -1; public WeekEnumerator(string[] days) { this.days = days; } public object Current { get { if (position == -1 || position >= days. Length) throw new InvalidOperationException(); return days[position]; } } public bool MoveNext() { if(position < days. Length - 1) { position++; return true; } else return false; } public void Reset() { position = -1; } } class Week { string[] days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; public IEnumerator GetEnumerator() { return new WeekEnumerator(days); } } class Program { static void Main(string[] args) { Week week = new Week(); foreach(var day in week) { Console.WriteLine(day); } Console.Read(); } } } Endilikda Week sinfi o‘rnatilgan ro‘yxatdan emas, balki IEnumeratordan foydalanadi. Yuqoridagi misollarda interfeyslarning umumlashtirilmagan versiyalaridan foydalanishdi, ammo biz ularning umumlashtirilgan ikkilamlaridan ham foydalanishimiz mumkin: using System; using System.Collections; using System.Collections.Generic; namespace HelloApp { class Week { string[] days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; public IEnumerator { return new WeekEnumerator(days); } } class WeekEnumerator : IEnumerator { string[] days; int position = -1; public WeekEnumerator(string[] days) { this.days = days; } public string Current { get { if (position == -1 || position >= days. Length) throw new InvalidOperationException(); return days[position]; } } object IEnumerator.Current => throw new NotImplementedException(); public bool MoveNext() { if(position < days. Length - 1) { position++; return true; } else return false; } public void Reset() { position = -1; } public void Dispose() { } } class Program { static void Main(string[] args) { Week week = new Week(); foreach(var day in week) { Console.WriteLine(day); } Console.Read(); } } } Download 31.88 Kb. Do'stlaringiz bilan baham: |
ma'muriyatiga murojaat qiling