Adakah yang bisa menjelaskan IEnumerable dan IEnumerator kepada saya?
misalnya, kapan menggunakannya lebih dulu? apa perbedaan antara IEnumerable dan IEnumerator? Mengapa kita perlu menggunakannya?
Adakah yang bisa menjelaskan IEnumerable dan IEnumerator kepada saya?
misalnya, kapan menggunakannya lebih dulu? apa perbedaan antara IEnumerable dan IEnumerator? Mengapa kita perlu menggunakannya?
Jawaban:
misalnya, kapan menggunakannya lebih dulu?
Anda tidak menggunakan IEnumerable
"lebih" foreach
. Pelaksana IEnumerable
membuat menggunakan foreach
mungkin .
Ketika Anda menulis kode seperti:
foreach (Foo bar in baz)
{
...
}
itu secara fungsional setara dengan menulis:
IEnumerator bat = baz.GetEnumerator();
while (bat.MoveNext())
{
bar = (Foo)bat.Current
...
}
Dengan "setara secara fungsional," Maksud saya sebenarnya kompiler mengubah kode menjadi. Anda tidak dapat menggunakan foreach
pada baz
dalam contoh ini kecuali baz
alat IEnumerable
.
IEnumerable
berarti baz
mengimplementasikan metode
IEnumerator GetEnumerator()
The IEnumerator
objek yang metode ini kembali harus menerapkan metode
bool MoveNext()
dan
Object Current()
Metode pertama maju ke objek berikutnya di IEnumerable
objek yang membuat enumerator, kembali false
jika sudah selesai, dan yang kedua mengembalikan objek saat ini.
Apa pun di .Net yang dapat Anda ulangi dari implementasinya IEnumerable
. Jika Anda membangun kelas Anda sendiri, dan itu belum mewarisi dari kelas yang mengimplementasikan IEnumerable
, Anda dapat membuat kelas Anda dapat digunakan dalam foreach
pernyataan dengan menerapkan IEnumerable
(dan dengan membuat kelas enumerator bahwa GetEnumerator
metode baru akan kembali).
bool MoveNext()
metode dan Current
properti tipe apa pun. Pendekatan "mengetik bebek" ini diterapkan di C # 1.0 sebagai cara untuk menghindari tinju ketika menghitung koleksi tipe nilai.
iterator
?
Antarmuka IEnumerable dan IEnumerator
Untuk mulai memeriksa proses penerapan antarmuka .NET yang ada, mari kita lihat peran IEnumerable dan IEnumerator. Ingatlah bahwa C # mendukung kata kunci bernama foreach yang memungkinkan Anda untuk mengulangi isi dari jenis array apa pun:
// Iterate over an array of items.
int[] myArrayOfInts = {10, 20, 30, 40};
foreach(int i in myArrayOfInts)
{
Console.WriteLine(i);
}
Meskipun mungkin terlihat bahwa hanya tipe array yang dapat menggunakan konstruk ini, kebenaran dari masalahnya adalah semua tipe yang mendukung metode bernama GetEnumerator () dapat dievaluasi oleh konstruk foreach. Untuk menggambarkan, ikuti saya!
Misalkan kita memiliki kelas Garasi:
// 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);
}
}
Idealnya, akan lebih mudah untuk beralih di atas subtitle objek Garage menggunakan konstruksi foreach, seperti array nilai data:
// 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();
}
}
Sayangnya, kompiler memberi tahu Anda bahwa kelas Garage tidak mengimplementasikan metode bernama GetEnumerator (). Metode ini diformalkan oleh antarmuka IEnumerable, yang ditemukan bersembunyi di dalam namespace System.Collections. Kelas atau struktur yang mendukung perilaku ini mengiklankan bahwa mereka dapat mengekspos subitem yang terkandung ke pemanggil (dalam contoh ini, kata kunci foreach itu sendiri). Berikut adalah definisi antarmuka .NET standar ini:
// This interface informs the caller
// that the object's subitems can be enumerated.
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
Seperti yang Anda lihat, metode GetEnumerator () mengembalikan referensi ke antarmuka lain bernama System.Collections.IEnumerator. Antarmuka ini menyediakan infrastruktur untuk memungkinkan pemanggil melintasi objek internal yang terkandung oleh wadah yang kompatibel dengan 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.
}
Jika Anda ingin memperbarui tipe Garage untuk mendukung antarmuka ini, Anda bisa menempuh jalan panjang dan mengimplementasikan setiap metode secara manual. Meskipun Anda tentu saja bebas untuk menyediakan versi GetEnumerator (), MoveNext (), Current, dan Reset () yang disesuaikan, ada cara yang lebih sederhana. Karena tipe System.Array (dan juga banyak kelas koleksi lainnya) sudah mengimplementasikan IEnumerable dan IEnumerator, Anda bisa mendelegasikan permintaan ke System.Array sebagai berikut:
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();
}
}
Setelah Anda memperbarui tipe Garage, Anda dapat menggunakan tipe itu dengan aman di dalam konstruksi C # foreach. Selanjutnya, mengingat bahwa metode GetEnumerator () telah didefinisikan secara publik, pengguna objek juga dapat berinteraksi dengan tipe 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);
Namun, jika Anda lebih suka menyembunyikan fungsi IEnumerable dari tingkat objek, cukup gunakan implementasi antarmuka eksplisit:
IEnumerator IEnumerable.GetEnumerator()
{
// Return the array object's IEnumerator.
return carArray.GetEnumerator();
}
Dengan melakukannya, pengguna objek biasa tidak akan menemukan metode GetEnumerator () Garage, sedangkan konstruksi foreach akan mendapatkan antarmuka di latar belakang bila diperlukan.
Diadaptasi dari Pro C # 5.0 dan .NET 4.5 Framework
Garage
yang didapat carArray
? Dengan begitu Anda tidak perlu menerapkan GetEnumerator
sendiri, karena Array
sudah melakukan ini. Misalnyaforeach(Car c in carLot.getCars()) { ... }
Menerapkan IEnumerable berarti kelas Anda mengembalikan objek IEnumerator:
public class People : IEnumerable
{
IEnumerator IEnumerable.GetEnumerator()
{
// return a PeopleEnumerator
}
}
Menerapkan IEnumerator berarti kelas Anda mengembalikan metode dan properti untuk iterasi:
public class PeopleEnumerator : IEnumerator
{
public void Reset()...
public bool MoveNext()...
public object Current...
}
Itulah bedanya.
Pertama, penjelasan tanpa kode, lalu saya tambahkan nanti.
Katakanlah Anda menjalankan perusahaan penerbangan. Dan di setiap pesawat Anda ingin mengetahui informasi tentang penumpang yang terbang di pesawat. Pada dasarnya Anda ingin dapat "melintasi" pesawat. Dengan kata lain, Anda ingin dapat mulai di kursi depan, dan kemudian berjalan ke bagian belakang pesawat, menanyakan beberapa penumpang informasi: siapa mereka, dari mana mereka berasal dll. Pesawat terbang hanya dapat melakukan ini , jika memang:
Mengapa persyaratan ini? Karena itulah yang diperlukan antarmuka.
Jika ini adalah informasi yang berlebihan, yang perlu Anda ketahui adalah bahwa Anda ingin dapat mengajukan beberapa pertanyaan kepada setiap penumpang di pesawat, mulai dari yang pertama dan berjalan ke yang terakhir.
Apa artinya dihitung?
Jika sebuah maskapai penerbangan "dapat dihitung", ini berarti bahwa HARUS ada pramugari yang hadir di pesawat, yang tugas satu-satunya adalah menghitung - dan pramugari ini HARUS menghitung dengan cara yang sangat spesifik:
Prosedur Penghitungan
Kapten maskapai menginginkan laporan tentang setiap penumpang ketika dan ketika mereka diselidiki atau dihitung. Jadi setelah berbicara dengan orang yang duduk di kursi pertama, pramugari / konter kemudian melapor kepada kapten, dan ketika laporan diberikan, konter mengingat posisi tepatnya di lorong dan terus menghitung tepat di mana dia pergi mati.
Dengan cara ini kapten selalu dapat memiliki informasi tentang orang yang sedang diselidiki. Dengan begitu, jika dia mengetahui bahwa orang ini menyukai Manchester City, maka dia dapat memberikan perlakuan istimewa pada penumpang tersebut, dll.
Mari kita ikat ini dengan IEnumerables
Seorang enumerable hanyalah kumpulan penumpang di pesawat. Hukum Penerbangan Sipil - ini pada dasarnya adalah aturan yang harus diikuti oleh semua jumlah IEnumerable. Setiap kali pramugari pergi ke kapten dengan informasi penumpang, kami pada dasarnya 'menyerahkan' penumpang ke kapten. Kapten pada dasarnya dapat melakukan apapun yang dia inginkan dengan penumpang - kecuali mengatur ulang penumpang di pesawat. Dalam hal ini, mereka diberikan perlakuan istimewa jika mereka mengikuti 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)
Ringkasan
Dengan kata lain, sesuatu dapat diperhitungkan jika memiliki penghitung . Dan kontra keharusan (pada dasarnya): (i) ingat tempatnya ( state ), (ii) dapat bergerak ke depan , (iii) dan tahu tentang saat orang yang ia berurusan dengan.
Enumerable hanyalah sebuah kata mewah untuk "countable". Dengan kata lain, enumerable memungkinkan Anda untuk 'menghitung' (yaitu menghitung).
IEnumerable mengimplementasikan GetEnumerator. Ketika dipanggil, metode itu akan mengembalikan IEnumerator yang mengimplementasikan MoveNext, Reset dan Current.
Jadi ketika kelas Anda mengimplementasikan IEnumerable, Anda mengatakan bahwa Anda dapat memanggil metode (GetEnumerator) dan mendapatkan objek baru yang dikembalikan (sebuah IEnumerator) yang dapat Anda gunakan dalam satu loop seperti foreach.
Menerapkan IEnumerable memungkinkan Anda untuk mendapatkan IEnumerator untuk daftar.
IEnumerator memungkinkan akses berurutan gaya foreach ke item dalam daftar, menggunakan kata kunci hasil.
Sebelum implementasi foreach (di Java 1.4, misalnya), cara untuk mengulang daftar adalah untuk mendapatkan enumerator dari daftar, kemudian meminta item "berikutnya" dalam daftar, selama nilai dikembalikan sebagai yang berikutnya item bukan nol. Foreach hanya melakukan itu secara implisit sebagai fitur bahasa, dengan cara yang sama yang mengunci () mengimplementasikan kelas Monitor di belakang layar.
Saya berharap foreach bekerja pada daftar karena mereka mengimplementasikan IEnumerable.
Pikirkan benda yang bisa dihitung sebagai daftar, tumpukan, pohon.
IEnumerable dan IEnumerator (dan rekan-rekan generik mereka IEnumerable <T> dan IEnumerator <T>) adalah antarmuka dasar dari implementasi iterator di koleksi .Net Framework Class Libray .
IEnumerable adalah antarmuka paling umum yang akan Anda lihat di sebagian besar kode di luar sana. Ini memungkinkan foreach loop, generator (think yield ) dan karena antarmuka yang kecil, ini digunakan untuk membuat abstraksi yang ketat. IEnumerable tergantung pada IEnumerator .
IEnumerator , di sisi lain, menyediakan antarmuka iterasi yang sedikit lebih rendah. Ini disebut sebagai iterator eksplisit yang memberi programmer lebih banyak kontrol atas siklus iterasi.
IEnumerable adalah antarmuka standar yang memungkinkan pengulangan koleksi yang mendukungnya (pada kenyataannya, semua jenis koleksi yang dapat saya pikirkan saat ini mengimplementasikan IEnumerable ). Dukungan kompiler memungkinkan fitur bahasa seperti foreach
. Secara umum, ini memungkinkan implementasi iterator implisit ini .
foreach (var value in list)
Console.WriteLine(value);
Saya pikir foreach
loop adalah salah satu alasan utama untuk menggunakan antarmuka IEnumerable . foreach
memiliki sintaksis yang sangat ringkas dan sangat mudah dipahami dibandingkan dengan gaya C klasik untuk loop di mana Anda perlu memeriksa berbagai variabel untuk melihat apa yang dilakukannya.
Mungkin fitur yang kurang diketahui adalah bahwa IEnumerable juga memungkinkan generator di C # dengan penggunaan yield return
dan yield break
pernyataan.
IEnumerable<Thing> GetThings() {
if (isNotReady) yield break;
while (thereIsMore)
yield return GetOneMoreThing();
}
Skenario umum lainnya dalam praktik adalah menggunakan IEnumerable untuk memberikan abstraksi minimalis. Karena itu adalah antarmuka sangat kecil dan hanya-baca, Anda didorong untuk mengekspos koleksi Anda sebagai IEnumerable (bukan List misalnya). Dengan begitu Anda bebas untuk mengubah implementasi Anda tanpa melanggar kode klien Anda (misalnya, ubah Daftar ke LinkedList ).
Satu perilaku yang harus diperhatikan adalah bahwa dalam implementasi streaming (mis. Mengambil data baris demi baris dari database, alih-alih memuat semua hasil dalam memori terlebih dahulu) Anda tidak dapat mengulangi koleksi lebih dari sekali. Ini berbeda dengan koleksi dalam memori seperti Daftar , di mana Anda dapat mengulangi beberapa kali tanpa masalah. ReSharper, misalnya, memiliki inspeksi kode untuk kemungkinan enumerasi ganda dari IEnumerable .
IEnumerator, di sisi lain, adalah antarmuka di belakang layar yang membuat IEnumerble-foreach-magic bekerja. Sebenarnya, ini memungkinkan iterator eksplisit.
var iter = list.GetEnumerator();
while (iter.MoveNext())
Console.WriteLine(iter.Current);
Dalam pengalaman saya, IEnumerator jarang digunakan dalam skenario umum karena sintaksisnya lebih verbose dan semantik yang sedikit membingungkan (setidaknya bagi saya; eg MoveNext () mengembalikan nilai juga, yang namanya tidak disarankan sama sekali).
Saya hanya menggunakan IEnumerator di perpustakaan (kerangka yang sedikit lebih rendah) dan kerangka kerja di mana saya menyediakan antarmuka IEnumerable . Salah satu contoh adalah pustaka pemrosesan aliran data yang menyediakan serangkaian objek dalam satu foreach
lingkaran meskipun di balik layar data dikumpulkan menggunakan berbagai aliran file dan serialisasi.
Kode klien
foreach(var item in feed.GetItems())
Console.WriteLine(item);
Perpustakaan
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;
}
}
Menerapkan IEnumerable
pada dasarnya berarti bahwa objek dapat diulangi. Ini tidak selalu berarti array karena ada daftar tertentu yang tidak dapat diindeks tetapi Anda dapat menghitungnya.
IEnumerator
adalah objek aktual yang digunakan untuk melakukan iterasi. Ini mengontrol bergerak dari satu objek ke yang berikutnya dalam daftar.
Sebagian besar waktu, IEnumerable
& IEnumerator
digunakan secara transparan sebagai bagian dari foreach
loop.
Perbedaan antara IEnumerable dan IEnumerator:
Setiap kali kami meneruskan koleksi IEnumerable ke fungsi lain, ia tidak tahu posisi item / objek saat ini (tidak tahu item mana yang dieksekusi)
IEnumerable memiliki satu metode GetEnumerator ()
public interface IEnumerable<out T> : IEnumerable { IEnumerator<T> GetEnumerator(); }
IEnumerator memiliki satu properti yang disebut Current dan dua metode, Reset () dan MoveNext () (yang berguna untuk mengetahui posisi item saat ini dalam daftar).
public interface IEnumerator
{
object Current { get; }
bool MoveNext();
void Reset();
}
IEnumerable adalah kotak yang berisi Ienumerator. IEnumerable adalah antarmuka dasar untuk semua koleksi. foreach loop dapat beroperasi jika koleksi mengimplementasikan IEnumerable. Dalam kode di bawah ini menjelaskan langkah memiliki Enumerator kita sendiri. Pertama-tama mari kita tentukan Kelas kita yang akan kita buat koleksi.
public class Customer
{
public String Name { get; set; }
public String City { get; set; }
public long Mobile { get; set; }
public double Amount { get; set; }
}
Sekarang kita akan mendefinisikan Kelas yang akan bertindak sebagai koleksi untuk Pelanggan kelas kita. Perhatikan bahwa itu mengimplementasikan antarmuka IEnumerable. Sehingga kita harus mengimplementasikan metode GetEnumerator. Ini akan mengembalikan Enumerator khusus kami.
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);
}
}
Sekarang kita akan membuat Enumerator khusus kita sendiri sebagai berikut. Jadi, kita harus mengimplementasikan metode 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.
}
}
Sekarang kita bisa menggunakan foreach loop pada koleksi kita seperti di bawah ini;
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();
}
}
Pemahaman tentang pola Iterator akan membantu Anda. Saya sarankan membaca yang sama.
Pada tingkat tinggi, pola iterator dapat digunakan untuk memberikan cara pengulangan standar melalui koleksi jenis apa pun. Kami memiliki 3 peserta dalam pola iterator, koleksi aktual (klien), agregator dan iterator. Agregat adalah kelas antarmuka / abstrak yang memiliki metode yang mengembalikan iterator. Iterator adalah kelas antarmuka / abstrak yang memiliki metode yang memungkinkan kita untuk beralih melalui koleksi.
Untuk menerapkan pola pertama-tama kita perlu menerapkan iterator untuk menghasilkan beton yang dapat diulang atas koleksi yang bersangkutan (klien). Kemudian koleksi (klien) mengimplementasikan agregator untuk mengembalikan instance dari iterator di atas.
Jadi pada dasarnya dalam c #, IEnumerable adalah agregat abstrak dan IEnumerator adalah Iterator abstrak. IEnumerable memiliki metode tunggal GetEnumerator yang bertanggung jawab untuk membuat instance IEnumerator dari tipe yang diinginkan. Koleksi seperti Daftar menerapkan IEnumerable.
Contoh. Mari kita anggap kita memiliki metode getPermutations(inputString)
yang mengembalikan semua permutasi string dan metode mengembalikan contohIEnumerable<string>
Untuk menghitung jumlah permutasi, kita dapat melakukan sesuatu seperti di bawah ini.
int count = 0;
var permutations = perm.getPermutations(inputString);
foreach (string permutation in permutations)
{
count++;
}
Kompiler c # kurang lebih mengubah konversi di atas menjadi
using (var permutationIterator = perm.getPermutations(input).GetEnumerator())
{
while (permutationIterator.MoveNext())
{
count++;
}
}
Jika Anda memiliki pertanyaan, jangan ragu untuk bertanya.
Kontribusi minor.
Seperti banyak dari mereka menjelaskan tentang 'kapan harus menggunakan' dan 'gunakan dengan foreach'. Saya berpikir untuk menambahkan Perbedaan Negara Lain di sini seperti yang diminta dalam pertanyaan tentang perbedaan antara kedua IEnumerable dan IEnumerator.
Saya membuat contoh kode di bawah ini berdasarkan utas diskusi di bawah ini.
IEnumerable, IEnumerator vs foreach, kapan harus menggunakan apa perbedaan antara IEnumerator dan IEnumerable?
Enumerator mempertahankan status (posisi iterasi) antara panggilan fungsi sementara iterasi sebaliknya Enumerable tidak.
Berikut adalah contoh yang diuji dengan komentar untuk dipahami.
Para ahli harap tambahkan / koreksi saya.
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());
}
}
Saya perhatikan perbedaan-perbedaan ini:
A. Kita mengulang daftar dengan cara yang berbeda, foreach dapat digunakan untuk IEnumerable dan while loop untuk IEnumerator.
B. IEnumerator dapat mengingat indeks saat ini ketika kami beralih dari satu metode ke metode lain (ini mulai bekerja dengan indeks saat ini) tetapi IEnumerable tidak dapat mengingat indeks dan mereset indeks ke awal. Lebih banyak di video ini https://www.youtube.com/watch?v=jd3yUjGc9M0
IEnumerable
dan IEnumerator
keduanya adalah antarmuka dalam C #.
IEnumerable
adalah antarmuka yang mendefinisikan metode tunggal GetEnumerator()
yang mengembalikan IEnumerator
antarmuka.
Ini berfungsi untuk akses hanya baca ke koleksi yang mengimplementasikan yang IEnumerable
dapat digunakan dengan foreach
pernyataan.
IEnumerator
memiliki dua metode, MoveNext
dan Reset
. Ini juga memiliki properti yang disebut Current
.
Berikut ini menunjukkan implementasi IEnumerable dan 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
*/