Qualcuno può spiegarmi IEnumerable e IEnumerator?
per esempio, quando usarlo su foreach? qual è la differenza tra IEnumerable e IEnumerator? Perché dobbiamo usarlo?
Qualcuno può spiegarmi IEnumerable e IEnumerator?
per esempio, quando usarlo su foreach? qual è la differenza tra IEnumerable e IEnumerator? Perché dobbiamo usarlo?
Risposte:
per esempio, quando usarlo su foreach?
Non usi IEnumerable
"over" foreach
. L'implementazione IEnumerable
rende foreach
possibile l' utilizzo .
Quando scrivi codice come:
foreach (Foo bar in baz)
{
...
}
è funzionalmente equivalente alla scrittura:
IEnumerator bat = baz.GetEnumerator();
while (bat.MoveNext())
{
bar = (Foo)bat.Current
...
}
Per "funzionalmente equivalente", intendo che in realtà è quello in cui il compilatore trasforma il codice. Non è possibile utilizzare foreach
ilbaz
in questo esempio a meno che baz
implementa IEnumerable
.
IEnumerable
significa che baz
implementa il metodo
IEnumerator GetEnumerator()
Il IEnumerator
oggetto restituito da questo metodo deve implementare i metodi
bool MoveNext()
e
Object Current()
Il primo metodo avanza all'oggetto successivo in IEnumerable
che ha creato l'enumeratore, restituendo false
se è stato eseguito e il secondo restituisce l'oggetto corrente.
Qualunque cosa in .Net che puoi iterare sugli strumenti IEnumerable
. Se stai costruendo la tua classe e non eredita già da una classe che implementa IEnumerable
, puoi rendere la tua classe utilizzabile nelle foreach
istruzioni implementando IEnumerable
(e creando una classe enumeratrice che il suo nuovo GetEnumerator
metodo restituirà).
bool MoveNext()
metodo e una Current
proprietà di qualsiasi tipo. Questo approccio "tipizzazione anatra" è stato implementato in C # 1.0 come un modo per evitare il pugilato durante l'enumerazione di raccolte di tipi di valore.
iterator
?
Le interfacce IEnumerable e IEnumerator
Per iniziare a esaminare il processo di implementazione delle interfacce .NET esistenti, esaminiamo innanzitutto il ruolo di IEnumerable e IEnumerator. Ricorda che C # supporta una parola chiave denominata foreach che ti consente di scorrere i contenuti di qualsiasi tipo di array:
// Iterate over an array of items.
int[] myArrayOfInts = {10, 20, 30, 40};
foreach(int i in myArrayOfInts)
{
Console.WriteLine(i);
}
Sebbene possa sembrare che solo i tipi di array possano utilizzare questo costrutto, la verità è che qualsiasi tipo che supporti un metodo chiamato GetEnumerator () può essere valutato dal costrutto foreach. Per illustrare, seguimi!
Supponiamo di avere una classe Garage:
// 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);
}
}
Idealmente, sarebbe conveniente scorrere le voci secondarie dell'oggetto Garage usando il costrutto foreach, proprio come una matrice di valori di dati:
// 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();
}
}
Purtroppo, il compilatore ti informa che la classe Garage non implementa un metodo chiamato GetEnumerator (). Questo metodo è formalizzato dall'interfaccia IEnumerable, che si trova in agguato nello spazio dei nomi System.Collections. Le classi o le strutture che supportano questo comportamento pubblicizzano che sono in grado di esporre al chiamante elementi secondari contenuti (in questo esempio, la parola chiave foreach stessa). Ecco la definizione di questa interfaccia .NET standard:
// This interface informs the caller
// that the object's subitems can be enumerated.
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
Come puoi vedere, il metodo GetEnumerator () restituisce un riferimento a un'altra interfaccia denominata System.Collections.IEnumerator. Questa interfaccia fornisce l'infrastruttura per consentire al chiamante di attraversare gli oggetti interni contenuti nel contenitore compatibile con IEnumerable:
// 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.
}
Se desideri aggiornare il tipo di Garage per supportare queste interfacce, potresti prendere la strada lunga e implementare manualmente ogni metodo. Sebbene tu sia certamente libero di fornire versioni personalizzate di GetEnumerator (), MoveNext (), Current e Reset (), esiste un modo più semplice. Poiché il tipo System.Array (così come molte altre classi di raccolta) implementa già IEnumerable e IEnumerator, puoi semplicemente delegare la richiesta a System.Array come segue:
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();
}
}
Dopo aver aggiornato il tipo di Garage, puoi tranquillamente utilizzare il tipo all'interno del costrutto foreach di C #. Inoltre, dato che il metodo GetEnumerator () è stato definito pubblicamente, l'utente oggetto potrebbe anche interagire con il tipo 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);
Tuttavia, se si preferisce nascondere la funzionalità di IEnumerable a livello di oggetto, utilizzare semplicemente l'implementazione esplicita dell'interfaccia:
IEnumerator IEnumerable.GetEnumerator()
{
// Return the array object's IEnumerator.
return carArray.GetEnumerator();
}
In questo modo, l'utente dell'oggetto casuale non troverà il metodo GetEnumerator () di Garage, mentre il costrutto foreach otterrà l'interfaccia in background quando necessario.
Adattato da Pro C # 5.0 e .NET 4.5 Framework
Garage
ottenere carArray
? In questo modo non è necessario implementare GetEnumerator
te stesso, poiché Array
già lo fa. Ad esempioforeach(Car c in carLot.getCars()) { ... }
L'implementazione di IEnumerable significa che la tua classe restituisce un oggetto IEnumerator:
public class People : IEnumerable
{
IEnumerator IEnumerable.GetEnumerator()
{
// return a PeopleEnumerator
}
}
L'implementazione di IEnumerator significa che la tua classe restituisce i metodi e le proprietà per l'iterazione:
public class PeopleEnumerator : IEnumerator
{
public void Reset()...
public bool MoveNext()...
public object Current...
}
Questa è la differenza comunque.
Prima una spiegazione senza codice, poi la aggiungerò più avanti.
Diciamo che stai gestendo una compagnia aerea. E in ogni aereo vuoi sapere informazioni sui passeggeri che volano nell'aereo. Fondamentalmente vuoi essere in grado di "attraversare" l'aereo. In altre parole, vuoi essere in grado di iniziare dal sedile anteriore e poi avanzare verso la parte posteriore dell'aereo, chiedendo ai passeggeri alcune informazioni: chi sono, da dove vengono, ecc. Un aereo può fare solo questo , se è:
Perché questi requisiti? Perché è quello che richiede l'interfaccia.
Se questo è un sovraccarico di informazioni, tutto ciò che devi sapere è che vuoi essere in grado di porre alcune domande a ciascun passeggero dell'aereo, partendo dal primo e arrivando all'ultimo.
Cosa significa numerabile?
Se una compagnia aerea è "numerabile", ciò significa che DEVE essere presente un assistente di volo sull'aereo, il cui unico compito è contare - e che tale assistente di volo DEVE contare in un modo molto specifico:
Procedure di conteggio
Il capitano della compagnia aerea desidera un rapporto su ogni passeggero man mano che viene esaminato o conteggiato. Quindi, dopo aver parlato con la persona al primo posto, l'assistente di volo / segnalino quindi riporta al capitano e, quando viene dato il rapporto, il contatore ricorda la sua posizione esatta nella navata e continua a contare proprio dove ha lasciato off.
In questo modo il capitano è sempre in grado di avere informazioni sull'attuale persona indagata. In questo modo, se scopre che a questa persona piace Manchester City, allora può dare a quel passeggero un trattamento preferenziale ecc.
Legiamolo a IEnumerables
Un enumerabile è solo una raccolta di passeggeri su un aereo. La legge sull'aviazione civile - queste sono fondamentalmente le regole che tutti gli Enumerabili devono seguire. Ogni volta che l'assistente della compagnia aerea si rivolge al capitano con le informazioni del passeger, in pratica 'cediamo' il passeggero al capitano. Il capitano può praticamente fare quello che vuole con il passeggero, tranne riorganizzare i passeggeri sull'aereo. In questo caso, ricevono un trattamento preferenziale se seguono Manchester 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)
Sommario
In altre parole, qualcosa è numerabile se ha un contatore . E il contatore deve (in sostanza): (i) ricordare il suo posto ( stato ), (ii) essere in grado di spostarsi dopo , (iii) e conoscere la persona attuale con cui ha a che fare.
Enumerabile è solo una parola elaborata per "numerabile". In altre parole, un enumerabile consente di "enumerare" (ovvero contare).
IEnumerable implementa GetEnumerator. Quando viene chiamato, quel metodo restituirà un IEnumerator che implementa MoveNext, Reset e Current.
Pertanto, quando la tua classe implementa IEnumerable, stai dicendo che puoi chiamare un metodo (GetEnumerator) e ottenere un nuovo oggetto restituito (un IEnumerator) che puoi usare in un ciclo come foreach.
L'implementazione di IEnumerable consente di ottenere un IEnumerator per un elenco.
IEnumerator consente l'accesso sequenziale in stile foreach agli elementi nell'elenco, utilizzando la parola chiave yield.
Prima di procedere all'implementazione (ad esempio in Java 1.4), il modo per iterare un elenco era ottenere un enumeratore dall'elenco, quindi chiedergli l'elemento "successivo" nell'elenco, purché il valore restituito come successivo l'articolo non è nullo. Foreach lo fa semplicemente implicitamente come funzionalità del linguaggio, allo stesso modo in cui lock () implementa la classe Monitor dietro le quinte.
Mi aspetto che tutti gli elenchi funzionino perché implementano IEnumerable.
Pensa agli oggetti enumerabili come a liste, pile, alberi.
IEnumerable e IEnumerator (e le loro controparti generiche IEnumerable <T> e IEnumerator <T>) sono interfacce di base delle implementazioni di iteratori nelle raccolte Libray di classe .Net Framework .
IEnumerable è l'interfaccia più comune che vedresti nella maggior parte del codice là fuori. Abilita il ciclo foreach, i generatori (pensa alla resa ) e grazie alla sua piccola interfaccia, viene utilizzato per creare astrazioni strette. IEnumerable dipende da IEnumerator .
IEnumerator , d'altra parte, fornisce un'interfaccia di iterazione di livello leggermente inferiore. Viene chiamato iteratore esplicito che offre al programmatore un maggiore controllo sul ciclo di iterazione.
IEnumerable è un'interfaccia standard che consente l'iterazione su raccolte che la supportano (in effetti, tutti i tipi di raccolta che posso pensare oggi implementano IEnumerable ). Il supporto del compilatore consente funzionalità linguistiche come foreach
. In termini generali, consente questa implementazione iteratrice implicita .
foreach (var value in list)
Console.WriteLine(value);
Penso che il foreach
loop sia uno dei motivi principali per l'utilizzo delle interfacce IEnumerable . foreach
ha una sintassi molto sintetica e molto facile da capire rispetto al classico stile C per i loop in cui è necessario controllare le varie variabili per vedere cosa stava facendo.
Probabilmente una caratteristica meno nota è che IEnumerable abilita anche generatori in C # con l'uso di yield return
e yield break
istruzioni.
IEnumerable<Thing> GetThings() {
if (isNotReady) yield break;
while (thereIsMore)
yield return GetOneMoreThing();
}
Un altro scenario comune in pratica è l'utilizzo di IEnumerable per fornire astrazioni minimaliste. Poiché si tratta di un'interfaccia minuscola e di sola lettura, si consiglia di esporre le raccolte come IEnumerable (anziché come Elenco, ad esempio). In questo modo sei libero di modificare l'implementazione senza rompere il codice del tuo client (ad esempio, cambiare l'elenco in un elenco collegato ).
Un comportamento da tenere presente è che nelle implementazioni di streaming (ad esempio il recupero di dati riga per riga da un database, anziché caricare prima tutti i risultati in memoria) non è possibile scorrere più volte la raccolta. Ciò è in contrasto con le raccolte in memoria come Elenco , in cui è possibile ripetere più volte senza problemi. ReSharper, ad esempio, ha un'ispezione del codice per la possibile enumerazione multipla di IEnumerable .
IEnumerator, d'altra parte, è l'interfaccia dietro le quinte che fa funzionare IEnumerble-foreach-magic . A rigor di termini, consente iteratori espliciti.
var iter = list.GetEnumerator();
while (iter.MoveNext())
Console.WriteLine(iter.Current);
Nella mia esperienza, IEnumerator è usato raramente in scenari comuni a causa della sua sintassi più dettagliata e della semantica leggermente confusa (almeno per me; ad esempio MoveNext () restituisce anche un valore, che il nome non suggerisce affatto).
Ho usato IEnumerator solo in librerie e framework (di livello leggermente inferiore) in cui fornivo interfacce IEnumerable . Un esempio è una libreria di elaborazione del flusso di dati che fornisce serie di oggetti in un foreach
ciclo anche se i dati dietro le quinte sono stati raccolti usando vari flussi di file e serializzazioni.
Codice cliente
foreach(var item in feed.GetItems())
Console.WriteLine(item);
Biblioteca
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;
}
}
L'implementazione IEnumerable
significa essenzialmente che l'oggetto può essere ripetuto. Ciò non significa necessariamente che sia un array in quanto vi sono alcuni elenchi che non possono essere indicizzati ma è possibile elencarli.
IEnumerator
è l'oggetto effettivo utilizzato per eseguire le iterazioni. Controlla lo spostamento da un oggetto a quello successivo nell'elenco.
Il più delle volte, IEnumerable
e IEnumerator
vengono utilizzati in modo trasparente come parte di un foreach
ciclo.
Differenze tra IEnumerable e IEnumerator:
Ogni volta che passiamo una raccolta IEnumerable a un'altra funzione, non conosce la posizione corrente di item / object (non sa quale articolo sta eseguendo)
IEnumerable ha un metodo GetEnumerator ()
public interface IEnumerable<out T> : IEnumerable { IEnumerator<T> GetEnumerator(); }
IEnumerator ha una proprietà chiamata Current e due metodi, Reset () e MoveNext () (che è utile per conoscere la posizione corrente di un elemento in un elenco).
public interface IEnumerator
{
object Current { get; }
bool MoveNext();
void Reset();
}
IEnumerable è una casella che contiene Ienumerator. IEnumerable è l'interfaccia di base per tutte le raccolte. foreach loop può funzionare se la raccolta implementa IEnumerable. Nel codice seguente viene spiegato il passaggio per avere il nostro enumeratore. Definiamo prima la nostra classe di cui faremo la raccolta.
public class Customer
{
public String Name { get; set; }
public String City { get; set; }
public long Mobile { get; set; }
public double Amount { get; set; }
}
Ora definiremo la Classe che fungerà da raccolta per il nostro Cliente di classe. Si noti che sta implementando l'interfaccia IEnumerable. In modo che dobbiamo implementare il metodo GetEnumerator. Questo restituirà il nostro enumeratore personalizzato.
public class CustomerList : IEnumerable
{
Customer[] customers = new Customer[4];
public CustomerList()
{
customers[0] = new Customer { Name = "Bijay Thapa", City = "LA", Mobile = 9841639665, Amount = 89.45 };
customers[1] = new Customer { Name = "Jack", City = "NYC", Mobile = 9175869002, Amount = 426.00 };
customers[2] = new Customer { Name = "Anil min", City = "Kathmandu", Mobile = 9173694005, Amount = 5896.20 };
customers[3] = new Customer { Name = "Jim sin", City = "Delhi", Mobile = 64214556002, Amount = 596.20 };
}
public int Count()
{
return customers.Count();
}
public Customer this[int index]
{
get
{
return customers[index];
}
}
public IEnumerator GetEnumerator()
{
return customers.GetEnumerator(); // we can do this but we are going to make our own Enumerator
return new CustomerEnumerator(this);
}
}
Ora creeremo il nostro enumeratore personalizzato come segue. Quindi, dobbiamo implementare il metodo MoveNext.
public class CustomerEnumerator : IEnumerator
{
CustomerList coll;
Customer CurrentCustomer;
int currentIndex;
public CustomerEnumerator(CustomerList customerList)
{
coll = customerList;
currentIndex = -1;
}
public object Current => CurrentCustomer;
public bool MoveNext()
{
if ((currentIndex++) >= coll.Count() - 1)
return false;
else
CurrentCustomer = coll[currentIndex];
return true;
}
public void Reset()
{
// we dont have to implement this method.
}
}
Ora possiamo usare foreach loop sulla nostra collezione come di seguito;
class EnumeratorExample
{
static void Main(String[] args)
{
CustomerList custList = new CustomerList();
foreach (Customer cust in custList)
{
Console.WriteLine("Customer Name:"+cust.Name + " City Name:" + cust.City + " Mobile Number:" + cust.Amount);
}
Console.Read();
}
}
Una comprensione del modello Iterator ti sarà utile. Consiglio di leggere lo stesso.
Ad un livello elevato, il modello iteratore può essere utilizzato per fornire un modo standard di iterare attraverso raccolte di qualsiasi tipo. Abbiamo 3 partecipanti nel modello iteratore, la raccolta effettiva (client), l'aggregatore e l'iteratore. L'aggregato è un'interfaccia / classe astratta che ha un metodo che restituisce un iteratore. Iterator è un'interfaccia / classe astratta che ha metodi che ci consentono di scorrere attraverso una raccolta.
Per implementare il modello, dobbiamo prima implementare un iteratore per produrre un concreto che possa iterare sulla raccolta (client) interessata. Quindi la raccolta (client) implementa l'aggregatore per restituire un'istanza dell'iteratore sopra.
Quindi sostanzialmente in c #, IEnumerable è l'aggregato astratto e IEnumerator è l'Iteratore astratto. IEnumerable ha un unico metodo GetEnumerator che è responsabile della creazione di un'istanza di IEnumerator del tipo desiderato. Collezioni come Elenchi implementano IEnumerable.
Esempio. Supponiamo che abbiamo un metodo getPermutations(inputString)
che restituisce tutte le permutazioni di una stringa e che il metodo restituisce un'istanza diIEnumerable<string>
Per contare il numero di permutazioni potremmo fare qualcosa di simile al seguito.
int count = 0;
var permutations = perm.getPermutations(inputString);
foreach (string permutation in permutations)
{
count++;
}
Il compilatore c # più o meno converte quanto sopra in
using (var permutationIterator = perm.getPermutations(input).GetEnumerator())
{
while (permutationIterator.MoveNext())
{
count++;
}
}
Se avete domande, non esitate a chiedere.
Un contributo minore.
Come molti di loro spiegano "quando usare" e "usare con foreach". Ho pensato di aggiungere qui un'altra differenza di stati , come richiesto nella domanda sulla differenza tra IEnumerable e IEnumerator.
Ho creato l'esempio di codice riportato di seguito in base ai thread di discussione seguenti.
IEnumerable, IEnumerator vs foreach, quando usare qual è la differenza tra IEnumerator e IEnumerable?
L'enumeratore conserva lo stato (posizione di iterazione) tra le chiamate di funzione mentre le iterazioni invece Enumerable no.
Ecco l'esempio testato con commenti per capire.
Esperti per favore aggiungimi / correggimi.
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());
}
}
Ho notato queste differenze:
R. Ripetiamo l'elenco in modo diverso, foreach può essere utilizzato per IEnumerable e while loop per IEnumerator.
B. IEnumerator può ricordare l'indice corrente quando passiamo da un metodo all'altro (inizia a lavorare con l'indice corrente) ma IEnumerable non riesce a ricordare l'indice e reimposta l'indice all'inizio. Altro in questo video https://www.youtube.com/watch?v=jd3yUjGc9M0
IEnumerable
ed IEnumerator
entrambi sono interfacce in C #.
IEnumerable
è un'interfaccia che definisce un singolo metodo GetEnumerator()
che restituisce unIEnumerator
un'interfaccia.
Funziona per l'accesso in sola lettura a una raccolta che lo implementa IEnumerable
può essere utilizzata con foreach
un'istruzione.
IEnumerator
ha due metodi MoveNext
eReset
. Ha anche una proprietà chiamata Current
.
Quanto segue mostra l'implementazione di IEnumerable e IEnumerator.
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
*/