Iteratorlar bu-takrorlovchilar.
Iterator, asosan, qiymatlar to'plami ustida takrorlash uchun rentabellik bayonotidan foydalanadigan kod blokidir. Ushbu kod bloki usul, bayonot tanasini aks ettirishi yoki xususiyatlar blokini olishi mumkin.
Iterator ikkita maxsus yo'riqnomadan foydalanadi:
yield return: Qaytarilgan elementni aniqlaydi.
yield break: ketma-ketlikning boshqa elementlari yo'qligini bildiradi.
Ushbu misolni ko’rib chiqamiz.
using System;
using System.Collections;
namespace HelloApp
{
class Program
{
static void Main(string[] args)
{
Numbers numbers = new Numbers();
foreach (int n in numbers)
{
Console.WriteLine(n);
}
Console.ReadKey();
}
}
class Numbers
{
public IEnumerator GetEnumerator()
{
for(int i = 0; i < 6; i++)
{
yield return i * i;
}
}
}
}
Numbers sinfida GetEnumerator () usuli aslida iteratorni ifodalaydi. Qaytish rentabelligi ba'zi bir qiymatlarni qaytaradi (bu holda, raqamning kvadrati).
Dasturda foreach loopi yordamida biz Numbers ob'ekti ustida oddiy to'plam kabi takrorlashimiz mumkin. Har bir element foreach ko'chadan olinganida, rentabellikni qaytarish bayonoti ishga tushiriladi, bu bitta elementni qaytaradi va joriy holatni eslab qoladi.
Yana bir misol: aytaylik, bizda kitoblar ombori - Kitob ob'ektlarini aks ettiruvchi kutubxona to'plami mavjud. Ushbu to'plam bo'yicha takrorlash uchun rentabellik bayonotidan foydalanamiz:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
|
class Book
{
public Book(string name)
{
this.Name = name;
}
public string Name { get; set; }
}
class Library
{
private Book[] books;
public Library()
{
books = new Book[] { new Book("Ottsы i deti"), new Book("Voyna i mir"),
new Book("Yevgeniy Onegin") };
}
public int Length
{
get { return books.Length; }
}
public IEnumerator GetEnumerator()
{
for (int i = 0; i < books.Length; i++)
{
yield return books[i];
}
}
}
|
GetEnumerator () usuli iteratorni anglatadi. Oldingi tsikldagi kutubxona ob'ekti ustida takrorlanganda rentabellikni qaytaruvchi kitoblar deb nomlaymiz [i];. Hosildorlikni qaytarish to'g'risidagi bayonotga kirishda joriy joy saqlanib qoladi. Va foreach usuli yangi iteratsiyani olish uchun keyingi iteratsiyaga o'tsa, iterator o'sha joydan bajarishni boshlaydi.
Xo'sh, oldingi tsikldagi asosiy dasturda iteratorni amalga oshirish tufayli haqiqiy sanoq amalga oshiriladi:
1
2
3
4
|
foreach (Book b in library)
{
Console.WriteLine(b.Name);
}
|
GetEnumerator () usulida iteratorni amalga oshirishda for for loopidagi massiv ustida takrorlanayotgan bo'lsa ham, buni qilish shart emas. Biz rentabellik ko'rsatkichi bo'yicha bir nechta qo'ng'iroqlarni aniqlay olamiz:
1
2
3
4
5
6
|
IEnumerator IEnumerable.GetEnumerator()
{
yield return books[0];
yield return books[1];
yield return books[2];
}
|
Bunday holda, har safar rentabellikni qaytarish to'g'risidagi bayonot chaqirilganda, iterator ham joriy manzilni eslab qoladi va keyingi qo'ng'iroqlarda u yerdan boshlanadi.
Do'stlaringiz bilan baham: |