Kezdőoldal » Számítástechnika » Programozás » Pontosan mi az az IEnumerable...

Pontosan mi az az IEnumerable vagy IEnumartor?

Figyelt kérdés
Bármilyen szakkönyvben olvasom nincs leírva. Csak az, hogy megvalósítja az IEnumerable interfészt, impletemntálja az IENumareble interfészt...stb stb. De, hogy mi ez, mire jó, mikor használjuk, az sehol sem volt leírva vagy elmondva.
2020. szept. 18. 21:32
 1/6 anonim ***** válasza:
73%

Az "enumerable" amolyan listázhatóságot jelent.

Általában olyankor használják, mikor egy "kurzort" léptetsz elejétől a végéig (rendszerint next()-el) és ahol áll épp avval végezhetsz műveletet, current() az aktuális elemet szedi ki. Lényegében egy olyan adat sor, amin lépkedhetsz oda-vissza (visszát, ha támogatja az interfész).


Más nyelvekben Iterable interfészként hivatkoznak rá.


Ezek csak metódus interfészek, nyilván te mondod meg, hogy a next() mit csináljon. Azért interfészként használják, mert ha más-más objektumot is ellátsz vele, akkor arról is mondhatjuk, hogy "végig tudunk a tartalmán lépkedni".

2020. szept. 18. 21:41
Hasznos számodra ez a válasz?
 2/6 A kérdező kommentje:
Köszönöm.
2020. szept. 18. 21:55
 3/6 anonim ***** válasza:
73%

Ez az úgynevezett iterátor tervezési minta. Arra a problémára kínál megoldást, hogy van többféle felsorolható adatszerkezeted, például tömb vagy láncolt lista. Sőt, olyan adatszerkezet is szóba jöhet, aminek az elemei a bejárás során dinamikusan generáltak vagy stream-eltek, vagyis amíg be nem járod, az elemei és a sorozat számossága nem ismert. Ezeknek az adatszerkezeteknek a bejárását teszi lehetővé egy egységes felületen.


Ahhoz, hogy egy adatszerkezetet be tudj járni, úgy igazából három dolgot kell tudnod:

1) hányadik elemnél járok (ez csak a belső működéshez szükséges olyan adatszerkezeteknél, aminek az összes eleme ismert, és egy bizonyos elemet indexelve éred el)

2) rá tudok-e állni a következő elemre

3) mi az éppen kiválasztott elem értéke.


Ezt a programozási környezetek úgy szokták megoldani, hogy kínálnak két, többnyire generikus interfészt: IEnumerable<T> és IEnumerator<T>. Ezek közül az IEnumerable<T> nagyon egyszerű:


interface IEnumerable<out T> {

.. IEnumerator<T> GetEnumerator();

}


Ezt az interfészt kell implementálnod, ha azt szeretnéd, hogy az általad írt adatszerkezet felsorolhatóvá váljon. De ez nyilván hozza magával a következő interfészt, az IEnumerator<T>-t, ami az adatszerkezeted bejárását fogja lehetővé tenni:


interface IEnumerator<T> {

.. T Current { get; } //mi az éppen kiválasztott elem

.. bool MoveNext(); //rá tudtam-e lépni a következő elemre

}


Vagyis, ha csinálni akarok egy MyRandomIntEnumerable osztályt, amit szeretnék bejárhatóvá tenni ezzel a tervezési mintával, valami ilyen kódot fogok írni:


class MyRandomIntEnumerable : IEnumerable<int> {

.. private readonly int[] array;


.. public int this[int index] {

.. .. get => array[index];

.. }


.. public int Size {

.. .. get => array.Length;

.. }


.. public MyIntArray(int size) {

.. .. this.array = new int[size];

.. .. this.Generate(size);

.. }


.. private void Generate(int size) {

.. .. Random r = new Random();

.. .. for (int i = 0; i < size; i++) {

.. .. .. array[i] = r.Next(1, 10000);

.. .. }

.. }


.. public IEnumerator<int> GetEnumerator() {

.. .. return new MyRandomIntArrayIterator(this);

.. }

}


class MyRandomIntArrayIterator : IEnumerator<int> {

.. private int index = 0;

.. private readonly MyIntArray source;


.. public int Current {

.. .. get => source[index];

.. }


.. public bool MoveNext() {

.. .. if (index == source.Size)

.. .. .. return false;


.. .. index++;

.. .. return true;

.. }

}


Mint láthatod, az implementációja nem túl bonyolult. Viszont ez a tervezési minta magában a nyelvben is használva van. A foreach ciklus például pont ezen a tervezési mintán alapulva teszi lehetővé az adatszerkezet bejárását, vagyis ha az osztályom helyesen implementálja az IEnumerable<T> interfészt, azonnal használhatom ebben a fajta ciklusban:


MyRandomIntArray myarray = new MyRandomIntArray(10);

foreach (int i in myarray)

.. Console.WriteLine(i);


Másik hatalmas nagy hozománya a válaszom elején említett dinamikusan generált vagy streamelt adatsorok. Ezt a technikát lazy loadingnak is hívják, mivel az elemeket csak akkor töltjük be a memóriába, amikor valóban szükség van rájuk. Vegyük a következő példát, hogy van egy adatforrásom, ami marha sok adatot generál és fel kell dolgoznom:


[link]


Mint azt láthatod, ha a teljes adatsort betöltöd a memóriába, akkor ez nagyjából le is zabált 2 GB RAM-ot a feldolgozás során. De vessük be az iterátor mintát erre az esetre:


[link]


Ugyanannyi adatot dolgoztam fel, de mivel egyszerre csak egy adatot tartottam a memóriában, 2 GB helyett rögtön elég lett 7 MB a feldolgozáshoz.

2020. szept. 18. 22:47
Hasznos számodra ez a válasz?
 4/6 anonim ***** válasza:
73%

Eh, én a linkcsászár :D


Na még egyszer:


Vegyük a következő példát, hogy van egy adatforrásom, ami marha sok adatot generál és fel kell dolgoznom:

[link]


Mint azt láthatod, ha a teljes adatsort betöltöd a memóriába, akkor ez nagyjából le is zabált 2 GB RAM-ot a feldolgozás során. De vessük be az iterátor mintát erre az esetre:

[link]

2020. szept. 18. 22:51
Hasznos számodra ez a válasz?
 5/6 anonim ***** válasza:
73%
Erre a lazy loadingra mondok még egy jó példát. Van egy adatbázisod, benne 100 millió rekorddal, és mondjuk az adatbázisod fejlődése miatt egy migrációt kell végrehajtanod minden rekordon. Nyilván nem célszerű mind a 100 millió rekordot egyszerre lehúzni. A MySQL és sok más adatbázis-kiszolgáló lehetővé teszi azt, hogy a lekérdezés eredményének csak egy kis részét kérd le. Mondjuk úgy 1000 elemet egyszerre. Itt is nagyon jól ki tudod használni az iterátor mintát, hogy egy batch-ben 1000 rekordot lekérsz, feldolgozod, majd kéred a következő 1000 rekordot. És megint megvan az az eredmény, hogy nem kell 200 GB RAM-ot felhasználnia a szoftverednek.
2020. szept. 18. 23:02
Hasznos számodra ez a válasz?
 6/6 A kérdező kommentje:
Köszönöm neked is. Hasznos volt. :) Mentek a zöldek neked is.
2020. szept. 18. 23:11

További kérdések:




Minden jog fenntartva © 2025, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!