Czy ktoś może mi wyjaśnić liczbę mnogą i liczbę mnogą?

Czy ktoś może mi wyjaśnić liczbę mnogą i liczbę mnogą?

Na przykład, kiedy używać go na foreach? jaka jest różnica między liczbą mnogą a liczbą mnogą? Dlaczego musimy go używać?

Author: HoKy22, 2009-02-17

14 answers

Na przykład, kiedy używać go na foreach?

Nie używasz IEnumerable "over" foreach. Implementacja IEnumerable sprawia, że korzystanie foreach możliwe .

Kiedy piszesz kod w stylu:

foreach (Foo bar in baz)
{
   ...
}

Jest funkcjonalnie równoznaczne z zapisem:

IEnumerator bat = baz.GetEnumerator();
while (bat.MoveNext())
{
   bar = (Foo)bat.Current
   ...
}

Przez "ekwiwalent funkcjonalny" mam na myśli to, w co kompilator zamienia kod. Nie możesz użyć foreach na baz w tym przykładzie , chyba że baz implementuje IEnumerable.

IEnumerable oznacza, że baz implementuje metodę

IEnumerator GetEnumerator()

Obiekt IEnumerator, który zwraca ta metoda musi zaimplementować metody

bool MoveNext()

I

Object Current()

Pierwsza metoda przechodzi do następnego obiektu w obiekcie IEnumerable, który utworzył enumerator, zwracając false, jeśli zostało to zrobione, a druga zwraca bieżący obiekt.

Wszystko W. Net, Co można iterować przez implementacje IEnumerable. Jeśli budujesz własną klasę, A nie dziedziczy ona już z klasy implementując IEnumerable, możesz uczynić swoją klasę użyteczną w foreach poleceniach implementując IEnumerable (i tworząc klasę enumerator, którą zwróci nowa metoda GetEnumerator).

 205
Author: Robert Rossney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-12 22:49:49

Interfejs IEnumerable i IEnumerator

Aby rozpocząć badanie procesu implementacji istniejących interfejsów. NET, przyjrzyjmy się najpierw roli Licznik i Licznik. Przypomnijmy, że C# obsługuje słowo kluczowe o nazwie foreach, które pozwala na iteracja nad zawartością dowolnego typu tablicy:

// Iterate over an array of items.
int[] myArrayOfInts = {10, 20, 30, 40};
foreach(int i in myArrayOfInts)
{
   Console.WriteLine(i);
}

Chociaż może się wydawać, że tylko typy tablic mogą korzystać z tego konstruktu, prawda jest taka, że każdy typ obsługujący metodę o nazwie GetEnumerator() może być ocenione przez foreach construct.To / align= "left" /

Załóżmy, że mamy klasę garażową:

// Garage contains a set of Car objects.
public class Garage
{
   private Car[] carArray = new Car[4];
   // Fill with some Car objects upon startup.
   public Garage()
   {
      carArray[0] = new Car("Rusty", 30);
      carArray[1] = new Car("Clunker", 55);
      carArray[2] = new Car("Zippy", 30);
      carArray[3] = new Car("Fred", 30);
   }
}

Idealnie byłoby wygodnie iterację nad subitemami obiektu garażu za pomocą foreach konstruuj, podobnie jak tablicę wartości danych:

// This seems reasonable ...
public class Program
{
   static void Main(string[] args)
   {
      Console.WriteLine("***** Fun with IEnumerable / IEnumerator *****\n");
      Garage carLot = new Garage();
      // Hand over each car in the collection?
      foreach (Car c in carLot)
      {
         Console.WriteLine("{0} is going {1} MPH",
         c.PetName, c.CurrentSpeed);
      }
      Console.ReadLine();
   }
}

Niestety kompilator informuje, że Klasa Garage nie implementuje metody o nazwie GetEnumerator (). Metoda ta jest sformalizowana przez interfejs IEnumerable, który znajduje się w systemie.Kolekcje przestrzeń nazw. Klasy lub struktury wspierające to zachowanie reklamują, że są w stanie ujawnić zawarte subitems do wywołującego (w tym przykładzie samo słowo kluczowe foreach). Oto definicja tego standardowego interfejsu. NET:

// This interface informs the caller
// that the object's subitems can be enumerated.
public interface IEnumerable
{
   IEnumerator GetEnumerator();
}

Jak widać, metoda GetEnumerator() Zwraca odwołanie do innego interfejsu o nazwie System.Kolekcje./ Align = "left" / Interfejs ten zapewnia infrastrukturę umożliwiającą rozmówcy przemierzanie wewnętrznych obiektów zawartych w Pojemnik zgodny z liczbą mnogą:

// This interface allows the caller to
// obtain a container's subitems.
public interface IEnumerator
{
   bool MoveNext (); // Advance the internal position of the cursor.
   object Current { get;} // Get the current item (read-only property).
   void Reset (); // Reset the cursor before the first member.
}

Jeśli chcesz zaktualizować Typ garażu, aby obsługiwał te interfejsy, możesz wybrać długą drogę i zaimplementuj każdą metodę ręcznie. Chociaż z pewnością możesz zapewnić niestandardowe wersje GetEnumerator (), MoveNext (), Current I Reset (), jest prostszy sposób. Jako System.Array type (podobnie jak wiele innych klas kolekcji) implementuje już IEnumerable i IEnumerator, można po prostu przekazać żądanie do systemu.Array as następuje:

using System.Collections;
...
public class Garage : IEnumerable
{
   // System.Array already implements IEnumerator!
   private Car[] carArray = new Car[4];
   public Garage()
   {
      carArray[0] = new Car("FeeFee", 200);
      carArray[1] = new Car("Clunker", 90);
      carArray[2] = new Car("Zippy", 30);
      carArray[3] = new Car("Fred", 30);
   }
   public IEnumerator GetEnumerator()
   {
      // Return the array object's IEnumerator.
      return carArray.GetEnumerator();
   }
}

Po zaktualizowaniu typu garażu, możesz bezpiecznie używać tego typu w C# foreach construct. Ponadto, biorąc pod uwagę, że metoda GetEnumerator() została zdefiniowana publicznie, użytkownik obiektu może również wchodzić w interakcje z typem IEnumerator:

// Manually work with IEnumerator.
IEnumerator i = carLot.GetEnumerator();
i.MoveNext();
Car myCar = (Car)i.Current;
Console.WriteLine("{0} is going {1} MPH", myCar.PetName, myCar.CurrentSpeed);

Jeśli jednak wolisz ukryć funkcjonalność IEnumerable z poziomu obiektu, po prostu zrób użycie jawnej implementacji interfejsu:

IEnumerator IEnumerable.GetEnumerator()
{
  // Return the array object's IEnumerator.
  return carArray.GetEnumerator();
}

Czyniąc tak, zwykły użytkownik obiektu nie będzie znajdź metodę GetEnumerator (), podczas gdy foreach construct w razie potrzeby uzyska interfejs w tle.

Zaadaptowany z Pro C # 5.0 i. NET 4.5 Framework

 110
Author: Jahan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-31 00:29:04

Implementacja IEnumerable oznacza, że twoja klasa zwraca obiekt IEnumerator:

public class People : IEnumerable
{
    IEnumerator IEnumerable.GetEnumerator()
    {
        // return a PeopleEnumerator
    }
}

Implementacja IEnumerator oznacza, że twoja klasa zwraca metody i właściwości iteracji:

public class PeopleEnumerator : IEnumerator
{
    public void Reset()...

    public bool MoveNext()...

    public object Current...
}
To i tak różnica.
 55
Author: core,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-02 23:40:41

Wyjaśnienie za pomocą analogii + Code Walkthrough

Najpierw Wyjaśnienie bez kodu, potem dodam je później.

Załóżmy, że prowadzisz firmę lotniczą. A w każdym samolocie chcesz wiedzieć informacje o pasażerach latających w samolocie. Zasadniczo chcesz być w stanie "przemierzyć" samolot. Innymi słowy, chcesz być w stanie zacząć od przedniego siedzenia, a następnie pracować w kierunku tyłu samolotu, pytając pasażerów o informacje: kim są, skąd pochodzą itp. Samolot może to zrobić tylko wtedy, gdy:
  1. policzalne i
  2. jeśli ma licznik.

Jeśli nie ma 'licznika', a jeśli nie jest 'policzalny', nie zajdziesz zbyt daleko. dlaczego te wymagania? ponieważ tego wymaga interfejs.

Co oznacza policzalny?

Jeśli linia lotnicza jest "policzalna", oznacza to, że w samolocie musi być stewardessa, której jedynym zadaniem jest zliczanie - i ta stewardessa musi liczyć się w bardzo specyficzny sposób (zgodnie z Prawem Lotnictwa Cywilnego):

  1. Licznik/stewardessa musi startować przed pierwszym pasażerem (z przodu każdego, gdzie demonstruje bezpieczeństwo, jak założyć kamizelkę ratunkową itp.).
  2. on/ona (tj. stewardessa) musi "przejść dalej" do przejścia na pierwsze miejsce.
  3. on/ona ma następnie zarejestrować: (i) kto jest na miejscu, oraz (ii) ich aktualną lokalizację w / align = "left" /

Procedury Liczenia

Kapitan linii lotniczych chce raportu o każdym pasażerze, kiedy i kiedy są badani lub liczone. Tak więc po rozmowie z osobą na pierwszym miejscu, stewardessa / licznik zgłasza się do kapitana, a kiedy raport jest podany, licznik pamięta jego dokładną pozycję w przejściu i kontynuuje liczenie dokładnie tam, gdzie skończył.

W ten sposób kapitan zawsze może mieć informacje o obecna osoba badana. W ten sposób, jeśli dowie się, że ten osobnik lubi Manchester City, to może dać temu pasażerowi preferencyjne traktowanie itp.
  • Licznik działa, aż dotrze do końca samolotu.

Zwiążmy to z IEnumerables

  • / Align = "left" / Prawo Lotnictwa Cywilnego-są to w zasadzie zasady, których muszą przestrzegać wszyscy Za każdym razem, gdy stewardessa idzie do kapitana z informacją o przepustce, w zasadzie "oddajemy" pasażera kapitanowi. Kapitan może w zasadzie robić z pasażerem, co chce-z wyjątkiem przestawiania pasażerów w samolocie. W tym przypadku otrzymują preferencyjne traktowanie, jeśli podążają za Manchesterem City (ugh!)
    foreach (Passenger passenger in Plane)
    // the airline hostess is now at the front of the plane
    // and slowly making her way towards the back
    // when she get to a particular passenger she gets some information
    // about the passenger and then immediately heads to the cabin
    // to let the captain decide what to do with it
    { // <---------- Note the curly bracket that is here.
        // we are now cockpit of the plane with the captain.
        // the captain wants to give the passenger free 
        // champaign if they support manchester city
        if (passenger.supports_mancestercity())
        {
            passenger.getFreeChampaign();
        } else
        {
            // you get nothing! GOOD DAY SIR!
        }
    } //  <---- Note the curly bracket that is here!
          the hostess has delivered the information 
          to the captain and goes to the next person
          on the plane (if she has not reached the 
          end of the plane)
    

Podsumowanie

Innymi słowy, coś jest policzalne, jeśli ma licznik. I licznik musi (zasadniczo): (i) zapamiętać jego miejsce (Stan), (ii) być w stanie przenieść się dalej, (iii) i wiedzieć o bieżącej osobie, z którą ma do czynienia.

Enumerable to wymyślne słowo na "policzalny". Innymi słowy, enumerable pozwala na 'enumerate' (tj. liczyć).

 37
Author: BKSpurgeon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-24 04:33:15

IEnumerable implementuje GetEnumerator. Po wywołaniu ta metoda zwróci IEnumerator , który implementuje MoveNext, Reset i Current.

Tak więc, gdy twoja klasa implementuje IEnumerable, mówisz, że możesz wywołać metodę (GetEnumerator) i uzyskać nowy obiekt zwrócony (an IEnumerator), którego możesz użyć w pętli takiej jak foreach.

 22
Author: DavGarcia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-17 19:19:16

Implementacja IEnumerable pozwala uzyskać IEnumerator dla listy.

IEnumerator pozwala na sekwencyjny dostęp do elementów na liście za pomocą słowa kluczowego yield.

Przed implementacją foreach (na przykład w Javie 1.4), sposobem iteracji listy było uzyskanie enumeratora z listy, a następnie poproszenie go o "następny" element na liście, o ile wartość zwracana jako następny element nie jest null. Foreach po prostu czyni to niejawnie jako cechę językową, w w ten sam sposób, w jaki lock() implementuje klasę Monitor za kulisami.

Spodziewam się, że foreach działa na listach, ponieważ implementują liczbę.

 15
Author: Neil Barnwell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-17 19:12:48
  • obiekt implementujący IEnumerable pozwala innym na odwiedzenie każdego z jego elementów (przez enumeratora).
  • obiekt implementujący IEnumerator wykonuje iterację. Zapętla się nad mierzalnym obiektem.

Pomyśl o liczonych obiektach jak o listach, stosach, drzewach.

 13
Author: Lieven Keersmaekers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-08 04:19:34

IEnumerable i IEnumerator (oraz ich generyczne odpowiedniki IEnumerable i IEnumerator) są bazowymi interfejsami implementacji iteratora W .Net Framework class Libray collections .

IEnumerable jest najczęściej spotykanym interfejsem, który można zobaczyć w większości kodu. Umożliwia pętlę foreach, Generatory (think yield), a ze względu na niewielki interfejs służy do tworzenia ciasnych abstrakcji. IEnumerable zależy od IEnumerator .

z kolei IEnumerator zapewnia nieco niższy poziom interfejsu iteracji. Jest on określany jako jawny iterator , który daje programiście większą kontrolę nad cyklem iteracji.

IEnumerable

IEnumerable jest standardowym interfejsem, który umożliwia iterację nad zbiorami, które go obsługują(w rzeczywistości wszystkie typy kolekcji, o których mogę dziś myśleć implementują IEnumerable ). Obsługa kompilatora pozwala na funkcje językowe takie jak foreach. Ogólnie rzecz biorąc, umożliwia to domyślną implementację iteratora.

Pętla Foreach

foreach (var value in list)
  Console.WriteLine(value);

Myślę, że pętla foreach jest jednym z głównych powodów korzystania z IEnumerable interfejsów. foreach ma bardzo zwięzłą składnię i bardzo łatwy do zrozumienia w porównaniu do klasycznego C styl dla pętli, w których musisz sprawdzić różne zmienne, aby zobaczyć, co robi.

Yield Keyword

Prawdopodobnie mniejszy znane jest to, że IEnumerable włącza również Generatory W C# za pomocą instrukcji yield return i yield break.

IEnumerable<Thing> GetThings() {
   if (isNotReady) yield break;
   while (thereIsMore)
     yield return GetOneMoreThing();
}

Abstrakcje

Innym powszechnym scenariuszem w praktyce jest użycie IEnumerable do dostarczenia minimalistycznych abstrakcji. Ponieważ jest to minimalistyczny i tylko do odczytu interfejs, zachęcamy do eksponowania swoich zbiorów jako IEnumerable (zamiast na przykład List ). W ten sposób możesz swobodnie zmieniać swoje implementacja bez łamania kodu klienta (np. zmiana listy na LinkedList ).

Gotcha

Należy pamiętać, że w implementacjach strumieniowych (np. pobieranie danych wiersz po wierszu z bazy danych, zamiast wczytywania wszystkich wyników do pamięci) nie można iterować nad kolekcją więcej niż jeden raz. Jest to w przeciwieństwie do zbiorów w pamięci, takich jak List , gdzie można iterować wiele razy bez problemów. ReSharper, na przykład, ma sprawdzanie kodu dla możliwe wielokrotne wyliczenie liczby mnogiej.

IEnumerator

IEnumerator, z drugiej strony, jest interfejsem za kulisami, który sprawia, że IEnumerble-foreach-magic Działa. Ściśle mówiąc, umożliwia jawne Iteratory.

var iter = list.GetEnumerator();
while (iter.MoveNext())
    Console.WriteLine(iter.Current);

Z mojego doświadczenia IEnumerator jest rzadko używany w typowych scenariuszach ze względu na bardziej wyrazistą składnię i nieco mylącą semantykę (w przynajmniej dla mnie; np. MoveNext () zwraca również wartość, której nazwa wcale nie sugeruje).

Przypadek użycia dla IEnumerator

Używałem tylko IEnumerator w szczególności (nieco niższego poziomu) bibliotek i frameworków, w których dostarczałem IEnumerable interfejsy. Jednym z przykładów jest biblioteka przetwarzania strumienia danych, która dostarczała szereg obiektów w pętli foreach, mimo że dane za kulisami były gromadzone za pomocą różnych strumieni plików i seriale

Kod klienta

foreach(var item in feed.GetItems())
    Console.WriteLine(item);

Biblioteka

IEnumerable GetItems() {
    return new FeedIterator(_fileNames)
}

class FeedIterator: IEnumerable {
    IEnumerator GetEnumerator() {
        return new FeedExplicitIterator(_stream);
    }
}

class FeedExplicitIterator: IEnumerator {
    DataItem _current;

    bool MoveNext() {
        _current = ReadMoreFromStream();
        return _current != null;           
    }

    DataItem Current() {
        return _current;   
    }
}
 9
Author: ziya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-10 02:18:42

Implementacja IEnumerable zasadniczo oznacza, że obiekt może być iterowany. Nie musi to oznaczać, że jest to tablica, ponieważ istnieją pewne listy, których nie można zindeksować, ale można je wyliczyć.

IEnumerator jest rzeczywistym obiektem używanym do wykonywania iteracji. Kontroluje przemieszczanie się z jednego obiektu do następnego na liście.

Przez większość czasu, IEnumerable & IEnumerator są używane transparentnie jako część pętli foreach.

 8
Author: Dan Herbert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-17 19:19:00

Różnice między IEnumerable i IEnumerator:

  • liczba mnoga używa liczby mnogiej wewnętrznie.
  • IEnumerable nie wie, który element/obiekt jest wykonywany.
  • ilekroć przekazujemy IEnumerator do innej funkcji, zna on aktualną pozycję elementu / obiektu.
  • Ilekroć przekazujemy zbiór liczbowy do innej funkcji, to nie zna bieżącej pozycji elementu / obiektu(nie wie, który element jego executing)

    IEnumerable mają jedną metodę GetEnumerator()

public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}

IEnumerator posiada jedną właściwość current oraz dwie metody Reset i MoveNext (co jest przydatne do poznania bieżącej pozycji elementu na liście).

public interface IEnumerator
{
     object Current { get; }
     bool MoveNext();
     void Reset();
}
 5
Author: Ajay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-18 12:06:11

Zrozumienie wzorca iteratora będzie dla Ciebie pomocne. Polecam przeczytać to samo.

Wzór Iteratora

Na wysokim poziomie wzorzec iteratora może być użyty do zapewnienia standardowego sposobu iteracji poprzez zbiory dowolnego typu. Mamy 3 uczestników we wzorze iteratora, rzeczywista kolekcja (klient), agregator i iterator. Agregat jest klasą interfejsu / abstrakcji, która ma metodę, która zwraca iterator. Iterator jest Klasa interface / abstract, która posiada metody pozwalające na iterację poprzez zbiór.

aby zaimplementować wzorzec musimy najpierw zaimplementować iterator do wytworzenia betonu, który może iterować nad daną kolekcją (klient) Następnie kolekcja (klient) implementuje agregator, aby zwrócić instancję powyższego iteratora.

Oto diagram UML Wzór Iteratora

Więc zasadniczo w c#, IEnumerable jest zbiorem abstrakcyjnym i IEnumerator jest iteratorem abstrakcyjnym. IEnumerable posiada jedną metodę GetEnumerator, która jest odpowiedzialna za stworzenie instancji IEnumerator pożądanego typu. Zbiory takie jak listy implementują IEnumerable.

Przykład. Załóżmy, że mamy metodę getPermutations(inputString), która zwraca wszystkie permutacje ciągu znaków i że metoda zwraca instancję IEnumerable<string>

Aby policzyć liczbę permutacji możemy zrobić coś takiego jak poniżej.

 int count = 0;
        var permutations = perm.getPermutations(inputString);
        foreach (string permutation in permutations)
        {
            count++;
        }

C# kompilator mniej więcej konwertuje powyższe do

using (var permutationIterator = perm.getPermutations(input).GetEnumerator())
        {
            while (permutationIterator.MoveNext())
            {
                count++;
            }
        }
Jeśli masz jakieś pytania, nie wahaj się zapytać.
 4
Author: lalatnayak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-20 16:27:53

Drobny wkład.

Jak wiele z nich wyjaśnia "Kiedy używać" i "używać z foreach". Pomyślałem o dodaniu kolejnej różnicy Stanów tutaj, zgodnie z pytaniem o różnicę między obydwoma liczbami Ienumeratora.

Stworzyłem poniższy kod na podstawie poniższych wątków dyskusji.

IEnumerable, IEnumerator vs foreach, kiedy używać co Jaka jest różnica między Ienumeratorem a Ile?

Enumerator zachowuje stan (pozycję iteracji) pomiędzy wywołaniami funkcji, podczas gdy iteracje, których druga ręka Enumerable nie robi.

Oto testowany przykład z komentarzami do zrozumienia.

Eksperci proszę o dodanie / poprawienie mnie.

static void EnumerableVsEnumeratorStateTest()
{
    IList<int> numList = new List<int>();

    numList.Add(1);
    numList.Add(2);
    numList.Add(3);
    numList.Add(4);
    numList.Add(5);
    numList.Add(6);

    Console.WriteLine("Using Enumerator - Remembers the state");
    IterateFrom1to3(numList.GetEnumerator());

    Console.WriteLine("Using Enumerable - Does not Remembers the state");
    IterateFrom1to3Eb(numList);

    Console.WriteLine("Using Enumerable - 2nd functions start from the item 1 in the collection");
}

static void IterateFrom1to3(IEnumerator<int> numColl)
{
    while (numColl.MoveNext())
    {
        Console.WriteLine(numColl.Current.ToString());

        if (numColl.Current > 3)
        {
            // This method called 3 times for 3 items (4,5,6) in the collection. 
            // It remembers the state and displays the continued values.
            IterateFrom3to6(numColl);
        }
    }
}

static void IterateFrom3to6(IEnumerator<int> numColl)
{
    while (numColl.MoveNext())
    {
        Console.WriteLine(numColl.Current.ToString());
    }
}

static void IterateFrom1to3Eb(IEnumerable<int> numColl)
{
    foreach (int num in numColl)
    {
        Console.WriteLine(num.ToString());

        if (num>= 5)
        {
            // The below method invokes for the last 2 items.
            //Since it doesnot persists the state it will displays entire collection 2 times.
            IterateFrom3to6Eb(numColl);
        }
    }
}

static void IterateFrom3to6Eb(IEnumerable<int> numColl)
{
    Console.WriteLine();
    foreach (int num in numColl)
    {
        Console.WriteLine(num.ToString());
    }
}
 2
Author: Sai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:01

Zauważyłem te różnice:

A. iterujemy listę w inny sposób, foreach może być użyty dla IEnumerable I while dla IEnumerator.

B. IEnumerator może zapamiętać bieżący indeks, gdy przechodzimy z jednej metody do drugiej (zaczyna działać z bieżącym indeksem), ale IEnumerable nie może zapamiętać indeksu i resetuje indeks do początku. Więcej w tym filmie https://www.youtube.com/watch?v=jd3yUjGc9M0

 2
Author: RotatingWheel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-27 08:53:10
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Enudemo
{

    class Person
    {
        string name = "";
        int roll;

        public Person(string name, int roll)
        {
            this.name = name;
            this.roll = roll;
        }

        public override string ToString()
        {
            return string.Format("Name : " + name + "\t Roll : " + roll);
        }

    }


    class Demo : IEnumerable
    {
        ArrayList list1 = new ArrayList();

        public Demo()
        {
            list1.Add(new Person("Shahriar", 332));
            list1.Add(new Person("Sujon", 333));
            list1.Add(new Person("Sumona", 334));
            list1.Add(new Person("Shakil", 335));
            list1.Add(new Person("Shruti", 336));
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
           return list1.GetEnumerator();
        }
    }



    class Program
    {
        static void Main(string[] args)
        {
            Demo d = new Demo();  // Notice here. it is simple object but for 
                                //IEnumerator you can get the collection data

            foreach (Person X in d)
            {
                Console.WriteLine(X);
            }

            Console.ReadKey();
        }
    }
}
/*
Output : 

Name : Shahriar  Roll : 332
Name : Sujon     Roll : 333
Name : Sumona    Roll : 334
Name : Shakil    Roll : 335
Name : Shruti    Roll : 336
  */
 0
Author: Md Shahriar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-02 18:28:37