Ienumerable va ienumerator interfeysi metodlarini sinfda qayta aniqlash


Download 31.88 Kb.
bet1/3
Sana16.10.2023
Hajmi31.88 Kb.
#1704713
  1   2   3
Bog'liq
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)


{

}
Tanlanadigan kollektsiya IEnumerable interfeysini amalga oshirishi kerak.


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 GetEnumerator()


{
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:
  1   2   3




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