Iterator bu murakkab to'plamni amalga oshirish tafsilotlarini oshkor qilmasdan ketma-ket o'tishga imkon beradigan xatti-harakatlar modeli. Umumiy ma'lumot
"Iterator" naqshini DIY amalga oshirish
Download 293.02 Kb.
|
Mustaqil ish.
"Iterator" naqshini DIY amalga oshirish
C # da bir yo'nalishli iterator naqshini amalga oshirish uchun ikkita shartdan biri bajarilishi kerak. Birinchidan, siz oddiygina IEnumerable yoki uning umumiy IEnumerable C # da Iterator naqshidan foydalanish har doim oddiy va qulay bo'lgan; Foreach bayonoti bu funktsiya noto'g'ri bo'lmaguncha MoveNext-ni o'zingiz chaqirish orqali iteratorlar bilan ishlashni osonlashtiradi: var container = GetCustomContainer(); foreach (var i in container) Console.WriteLine("{0} ", i); Bizning amaliyotimizda Iterator naqshini amalga oshiradigan sinfni yig'ish sinfidan ajratish nafaqat Yagona javobgarlik printsipi (SRP), balki ahamiyatsiz sog'lom fikr bilan ham bog'liq. Shubhasiz, iteratsiya jarayoni to'plamning o'zi bilan jismonan bog'liq emas, lekin undan ham muhimroq omil shundaki, siz turli, mustaqil iteratsiya operatsiyalari uchun bir nechta iterator ob'ektlaridan foydalanishingiz mumkin, shuning uchun bizning amaliyotimizda GetEnumerator usuli har doim qaytariladi yangi ob'ekt. Ushbu dizayn naqshini amalga oshirish uchun biz konstruktor uchun to'plamni parametr sifatida qabul qiladigan va uni maydonlaridan birida saqlaydigan ichki sinfni yaratdik. Bundan tashqari, ushbu klass joriy indeksni (currentIndex) o'z ichiga oladi, bu to'plamdagi joriy elementga ishora qiladi, uni Current xususiyati yordamida olish mumkin. .NET idiomasiga ko'ra, iterator ob'ekti yaratilgandan so'ng, to'plamning birinchi elementi oldidagi elementni ko'rsatishi kerak (bizning holatda, bu joriy indeks -1 bo'lishi kerakligini anglatadi) va birinchi elementni ko'rsatishi kerak. MoveNext-ga birinchi qo'ng'iroqdan keyin to'plamda. Agar to'plamning keyingi elementiga o'tish muvaffaqiyatli bo'lsa, MoveNext usuli true qiymatini qaytarishi kerak, aks holda (agar biz butun to'plamni allaqachon bosib o'tgan bo'lsak), bu usul noto'g'ri qiymatini qaytarishi kerak (iterator ob'ekti oxirgi elementdan keyin joylashgan elementni ko'rsatishi kerak. kollektsiyadagi element). Qayta tiklash usuli iterator ob'ektini asl holatiga qaytarishi kerak va agar iterator ob'ekti noto'g'ri elementga ishora qilsa, joriy elementga (Joriy xususiyat) kirish InvalidOperationException istisnosini keltirib chiqarishi kerak. Iterator ob'ekti, shuningdek, to'plam yaratilgandan keyin o'zgartirilmasligiga e'tibor berishi kerak va agar joriy elementga to'plam o'zgartirilgandan so'ng kirish mumkin bo'lsa, InvalidOperationException ham tashlanishi kerak. Iterator bloki IEnumerator, IEnumerator Avtomatik yaratilgan sinf bir nechta majburiy va bir nechta ixtiyoriy qo'shimcha maydonlarni o'z ichiga oladi. Har bir yaratilgan sinf iterator ob'ektining joriy holatini kuzatib boradigan va MoveNext ni chaqirgandan so'ng iterator blokidagi keyingi kod blokini bajarishga davom etadigan holat mashinasini amalga oshiradi. Bu sinf __state maydonini (holat mashinasining holati), tashqi sinfga havolani (__this) va __joriy maydonni o'z ichiga oladi, ularning turi iterator ob'ekti tomonidan qaytarilgan element turiga mos keladi. Ixtiyoriy maydonlar GetEnumerator usulining mahalliy o'zgaruvchilariga mos keladigan maydonlar (bu holda, __i), shuningdek, ushbu usulning barcha parametrlari (chunki bu misolda GetEnumerator usuli hech qanday parametrlarni o'z ichiga olmaydi, mos keladigan maydonlar mavjud emas). Yaratilgan usullarning aksariyati juda oddiy. GetEnumerator usuli har safar oddiygina iteratorning nusxasini yaratadi va konstruktor parametrida holatning boshlang'ich qiymati bo'lgan butun son qiymatini o'tkazadi (bu qarorning ahamiyati IEnumeratorni amalga oshiradigan sinflarni ko'rib chiqishda aniq bo'ladi), shuningdek iteratorga konteynerning o'zi va uning barcha tarkibiga kirish imkonini beruvchi __this xususiyatini o'rnatadi; Current xususiyati iteratorning joriy qiymatini qaytaradi (__current o'zgaruvchisi), Reset usuli amalga oshirilmagan (va bu amalga oshirish xususiyati emas, bu C# tili spetsifikatsiyasida aniq ko'rsatilgan), Dispose usuli bo'sh (men bo'laman). keyin misol keltiring, agar bunday bo'lmasa) va butun asosiy ish MoveNext usuli bilan amalga oshiriladi. Bu MoveNext usuli bo'lib, u ilgari GetEnumerator usulida bo'lgan asosiy kodni o'z ichiga oladi va u iterator tomonidan qaytarilgan joriy qiymatni o'zgartirish uchun mas'ul bo'lgan davlat mashinasini amalga oshirishni ham o'z ichiga oladi. Shtat mashinasi bir qator "oldindan belgilangan" holatlarni (ular C # tili spetsifikatsiyasida tasvirlangan), shuningdek, soni amalga oshirishga bog'liq bo'lgan bir qator qo'shimcha holatlarni o'z ichiga oladi (aniqrog'i, rentabellik soniga bog'liq) bayonotlar). C# dasturlash tilida iteratorlar juda muhim rol o'ynaydi, chunki, masalan, LINQ 2 Objects-dan foydalanishning ko'pchiligi iteratorlar va ularning bajarilishiga asoslangan va bu nafaqat ba'zi kutubxonalarni ishlab chiqish va ulardan foydalanishga, balki ko'plab kundalik vazifalarni amalga oshirishga ham tegishli. Ko'pgina hollarda, dasturchi boshqa echimlarni topishi mumkin va iterator bloklaridan foydalanmaydi, biroq ularning yordami bilan juda oddiy va nafis hal qilinishi mumkin bo'lgan bir qator vazifalar mavjud, shuning uchun siz hali ham kerak bo'lsa. Download 293.02 Kb. Do'stlaringiz bilan baham: |
ma'muriyatiga murojaat qiling