IEnumerable ve IEnumerator'ı bana açıklayan var mı?
örneğin, ne zaman foreach üzerinde kullanılır? IEnumerable ve IEnumerator arasındaki fark nedir? Neden kullanmamız gerekiyor?
IEnumerable ve IEnumerator'ı bana açıklayan var mı?
örneğin, ne zaman foreach üzerinde kullanılır? IEnumerable ve IEnumerator arasındaki fark nedir? Neden kullanmamız gerekiyor?
Yanıtlar:
örneğin, ne zaman foreach üzerinde kullanılır?
IEnumerable
"Üzerinden" kullanmazsınız foreach
. Uygulamayı IEnumerable
kullanmayı foreach
mümkün kılar .
Gibi bir kod yazdığınızda:
foreach (Foo bar in baz)
{
...
}
işlevsel olarak yazmaya eşittir:
IEnumerator bat = baz.GetEnumerator();
while (bat.MoveNext())
{
bar = (Foo)bat.Current
...
}
"İşlevsel olarak eşdeğer" derken, derleyici kodu dönüştüren şey budur. Sen kullanamazsınız foreach
üzerinde baz
bu örnekte sürece baz
uygular IEnumerable
.
IEnumerable
baz
yöntemi uygulayan anlamına gelir
IEnumerator GetEnumerator()
IEnumerator
Bu yöntem döndürür yöntemleri uygulamak gerekir ki nesne
bool MoveNext()
ve
Object Current()
İlk yöntem IEnumerable
numaralandırıcıyı yaratan nesnede bir sonraki nesneye ilerler , false
eğer yapılırsa geri döner ve ikincisi geçerli nesneyi döndürür.
.Net üzerinde herhangi bir şey üzerinden yineleme yapabilirsiniz uygular IEnumerable
. Kendi sınıfınızı oluşturuyorsanız ve zaten uygulayan bir sınıftan miras almıyorsanız IEnumerable
, foreach
uygulayarak IEnumerable
(ve yeni GetEnumerator
yönteminin döndüreceği bir numaralandırıcı sınıfı oluşturarak) sınıfınızı ifadelerde kullanılabilir hale getirebilirsiniz .
bool MoveNext()
yönteme ve Current
herhangi bir tür özelliğine sahip bir tür örneğini döndüren bir GetEnumerator yöntemine sahip olmaları gerekir . Bu "ördek tipleme" yaklaşımı, C # 1.0'da, değer türü koleksiyonları numaralandırırken boksu önlemenin bir yolu olarak uygulanmıştır.
iterator
mi?
IEnumerable ve IEnumerator Arabirimleri
Mevcut .NET arabirimlerini uygulama sürecini incelemeye başlamak için, önce IEnumerable ve IEnumerator rolüne bakalım. C # 'ın, herhangi bir dizi türünün içeriğini yinelemenize izin veren foreach adlı bir anahtar kelimeyi desteklediğini hatırlayın:
// Iterate over an array of items.
int[] myArrayOfInts = {10, 20, 30, 40};
foreach(int i in myArrayOfInts)
{
Console.WriteLine(i);
}
Bu yapıdan sadece dizi türlerinin faydalanabileceği görünse de, konunun gerçeği, GetEnumerator () adında bir yöntemi destekleyen herhangi bir türdür, foreach yapısı tarafından değerlendirilebilir.
Bir Garaj sınıfımız olduğunu varsayalım:
// 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);
}
}
İdeal olarak, tıpkı bir veri değerleri dizisi gibi, foreach yapısını kullanarak Garaj nesnesinin alt öğelerini yinelemek uygun olacaktır:
// 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();
}
}
Ne yazık ki derleyici, Garage sınıfının GetEnumerator () adında bir yöntem uygulamadığını bildirir. Bu yöntem, System.Collections ad alanında gizlenen IEnumerable arabirimi tarafından resmileştirilmiştir. Bu davranışı destekleyen sınıflar veya yapılar, içerilen alt öğeleri arayana gösterebileceklerini bildirir (bu örnekte foreach anahtar sözcüğünün kendisi). İşte bu standart .NET arabiriminin tanımı:
// This interface informs the caller
// that the object's subitems can be enumerated.
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
Gördüğünüz gibi GetEnumerator () yöntemi, System.Collections.IEnumerator adlı başka bir arabirime başvuru döndürür. Bu arabirim, arayanın IEnumerable uyumlu kapsayıcıda bulunan dahili nesneleri geçmesine izin verecek altyapıyı sağlar:
// 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.
}
Garaj türünü bu arayüzleri destekleyecek şekilde güncellemek istiyorsanız, uzun yoldan gidebilir ve her yöntemi manuel olarak uygulayabilirsiniz. GetEnumerator (), MoveNext (), Current ve Reset () 'in özelleştirilmiş sürümlerini sağlamakta özgürsünüz, ancak daha basit bir yol var. System.Array türü (ve diğer birçok koleksiyon sınıfının yanı sıra) zaten IEnumerable ve IEnumerator uyguladığından, isteği System.Array öğesine aşağıdaki şekilde atayabilirsiniz:
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();
}
}
Garaj türünüzü güncelledikten sonra, C # foreach yapısı içindeki türü güvenle kullanabilirsiniz. Ayrıca, GetEnumerator () yönteminin genel olarak tanımlandığı göz önüne alındığında, nesne kullanıcısı IEnumerator türüyle de etkileşime girebilir:
// 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);
Ancak, IEnumerable işlevini nesne düzeyinden gizlemeyi tercih ediyorsanız, açık arabirim uygulamasını kullanın:
IEnumerator IEnumerable.GetEnumerator()
{
// Return the array object's IEnumerator.
return carArray.GetEnumerator();
}
Bu şekilde, geçici nesne kullanıcısı Garage'ın GetEnumerator () yöntemini bulamazken, foreach yapısı gerektiğinde arka planda arabirimi elde eder.
Pro C # 5.0 ve .NET 4.5 Framework'ten uyarlanmıştır
Garage
ki carArray
? Bu şekilde GetEnumerator
kendinizi uygulamak zorunda değilsiniz , çünkü bunu Array
zaten yapıyor. Örn.foreach(Car c in carLot.getCars()) { ... }
IEnumerable uygulamak, sınıfınızın bir IEnumerator nesnesi döndürdüğü anlamına gelir:
public class People : IEnumerable
{
IEnumerator IEnumerable.GetEnumerator()
{
// return a PeopleEnumerator
}
}
IEnumerator uygulaması, sınıfınızın yineleme için yöntemleri ve özellikleri döndüreceği anlamına gelir:
public class PeopleEnumerator : IEnumerator
{
public void Reset()...
public bool MoveNext()...
public object Current...
}
Zaten fark bu.
Önce kodsuz bir açıklama, daha sonra ekleyeceğim.
Diyelim ki bir havayolu şirketi işletiyorsunuz. Ve her düzlemde, uçakta uçan yolcular hakkında bilgi edinmek istersiniz. Temel olarak uçağı "hareket ettirmek" istersiniz. Başka bir deyişle, ön koltukta başlayabilmek ve daha sonra uçağın arkasına doğru ilerlemek, yolculara bazı bilgiler sorabilmek istiyorsunuz: kim olduklarını, nereden geldiklerini vb. Bir uçak sadece bunu yapabilir , Öyleyse:
Neden bu gereksinimler? Çünkü arayüzün gerektirdiği şey bu.
Bu aşırı bilgi yükü ise, bilmeniz gereken tek şey, uçaktaki her yolcuya ilkinden başlayarak sonuncuya doğru yol almak için bazı sorular sormak isteyebileceğinizdir.
Sayılabilir ne demektir?
Bir havayolu "sayılabilir" ise, bu, uçakta mevcut olan bir uçuş görevlisi olması gerektiği anlamına gelir, tek işi saymaktır - ve bu uçuş görevlisi çok özel bir şekilde saymak GEREKİR:
Sayma Prosedürleri
Havayolu kaptanı, soruşturulduğu veya sayılacağı zaman her yolcu hakkında bir rapor istiyor. Böylece birinci koltuktaki kişiyle konuştuktan sonra, uçuş görevlisi / sayaç kaptana rapor verir ve rapor verildiğinde, sayaç koridordaki tam konumunu hatırlar ve kaldığı yerden saymaya devam eder kapatır.
Bu şekilde kaptan, araştırılmakta olan kişi hakkında her zaman bilgi sahibi olur. Bu şekilde, bu bireyin Manchester City'yi sevdiğini öğrenirse, o yolcuya tercihli muamele vb. Verebilir.
Bunu IEnumerables ile bağlayalım
Bir numaralandırılabilir sadece bir uçakta yolcuların bir koleksiyon. Sivil Havacılık Kanunu - bunlar temel olarak tüm IEnumerable'ların uyması gereken kurallardır. Havayolu görevlisi passeger bilgileriyle kaptana her gittiğinde, temelde yolcuyu kaptana 'veriyoruz'. Kaptan temel olarak yolcu ile istediği her şeyi yapabilir - uçaktaki yolcuları yeniden düzenlemek dışında. Bu durumda, Manchester City'yi izlerse onlara tercihli tedavi verilir (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)
özet
Başka bir deyişle, bir sayacı varsa bir şey sayılabilir . Ve sayaç (temel olarak): (i) yerini ( durumunu ) hatırlar , (ii) bir sonraki adımda hareket edebilir , (iii) ve uğraştığı şu anki kişiyi bilir .
Enumerable sadece "sayılabilir" için süslü bir kelime. Başka bir deyişle, bir numaralandırılabilir 'numaralandırmanıza (yani saymanıza) izin verir.
IEnumerable GetEnumerator uygular. Bu yöntem çağrıldığında MoveNext, Reset ve Current uygulayan bir IEnumerator döndürür .
Böylece sınıfınız IEnumerable uyguladığında, bir yöntemi (GetEnumerator) çağırabileceğinizi ve foreach gibi bir döngüde kullanabileceğiniz yeni bir nesne (IEnumerator) döndüğünüzü söylersiniz.
IEnumerable uygulaması, bir liste için bir IEnumerator almanızı sağlar.
IEnumerator, verim anahtar sözcüğünü kullanarak listedeki öğelere her biçime sıralı erişime izin verir.
Her uygulamadan önce (örneğin Java 1.4'te), bir listeyi yinelemenin yolu listeden bir numaralandırıcı almak ve ardından bir sonraki gibi döndürülen değer olduğu sürece listeden "sonraki" öğeyi istemektir. öğe boş değil. Foreach bunu bunu bir dil özelliği olarak, lock () öğesinin perde sınıfının arkasına uyguladığı şekilde yapar.
IEnumerable uyguladıkları için listelerde foreach çalışmaları bekliyorum.
Numaralandırılabilir nesneleri listeler, yığınlar, ağaçlar olarak düşünün.
IEnumerable ve IEnumerator (ve genel benzerleri IEnumerable <T> ve IEnumerator <T>) .Net Framework Sınıfı Libray koleksiyonlarındaki yineleyici uygulamalarının temel arabirimleridir .
IEnumerable , kodun çoğunda gördüğünüz en yaygın arabirimdir. Foreach döngüsünü, jeneratörleri (düşünen verim ) sağlar ve küçük arayüzü nedeniyle sıkı soyutlamalar oluşturmak için kullanılır. IEnumerable, IEnumerator'a bağlıdır .
IEnumerator , diğer taraftan, biraz daha düşük seviyeli bir yineleme arabirimi sağlar. Programcıya yineleme döngüsü üzerinde daha fazla kontrol sağlayan açık yineleyici olarak adlandırılır .
IEnumerable, onu destekleyen koleksiyonlar üzerinde yinelemeyi sağlayan standart bir arabirimdir (aslında, bugün aklıma gelen tüm koleksiyon türleri IEnumerable uygular ). Derleyici desteği gibi dil özelliklerine izin verir foreach
. Genel olarak, bu örtük yineleyici uygulamasını mümkün kılar .
foreach (var value in list)
Console.WriteLine(value);
foreach
Döngü IEnumerable arabirimlerini kullanmanın ana nedenlerinden biri olduğunu düşünüyorum . foreach
çok değişken bir sözdizimine sahiptir ve ne yaptığını görmek için çeşitli değişkenleri kontrol etmeniz gereken döngüler için klasik C stiline kıyasla anlaşılması çok kolaydır .
Muhtemelen daha az bilinen bir özellik, IEnumerable'ın C # 'daki jeneratörlerinyield return
ve yield break
ifadelerinin kullanımı ile etkinleştirilmesidir .
IEnumerable<Thing> GetThings() {
if (isNotReady) yield break;
while (thereIsMore)
yield return GetOneMoreThing();
}
Uygulamadaki bir diğer yaygın senaryo, minimalist soyutlamalar sağlamak için IEnumerable kullanmaktır . Küçük ve salt okunur bir arayüz olduğundan, koleksiyonlarınızı IEnumerable olarak ( örneğin Liste yerine) göstermeniz önerilir . Bu şekilde, müşterinizin kodunu kırmadan uygulamanızı değiştirebilirsiniz ( örneğin Listeyi bir LinkedList olarak değiştirin ).
Bir davranış (örneğin bir veritabanından satırda veri satırı almak yerine öncelikle hafızada sonucu yüklenirken) akışı uygulamalarda olmasıdır Dikkat edilmesi gereken olamaz yinelerler kereden fazla koleksiyonu üzerinde. Bu, List gibi bellekte olmayan koleksiyonların aksine , sorunsuz bir şekilde birden çok kez yineleyebileceğiniz. Örneğin ReSharper, olası IEnumerable çoklu numaralandırması için bir kod denetimine sahiptir .
IEnumerator, diğer taraftan, IEnumerble-foreach-magic çalışmasını sağlayan sahne arkası arabirimidir . Açık konuşmak gerekirse, açık yineleyiciler sağlar.
var iter = list.GetEnumerator();
while (iter.MoveNext())
Console.WriteLine(iter.Current);
Deneyimlerime göre IEnumerator , daha ayrıntılı sözdizimi ve biraz kafa karıştırıcı anlambiliminden dolayı yaygın senaryolarda nadiren kullanılır (en azından benim için; örneğin MoveNext () , adın hiç önermediği bir değer de döndürür).
Yalnızca IEnumerator'ı ( IEnumerable arabirimleri sağladığım) özellikle (biraz daha düşük düzeyde) kitaplıklar ve çerçeveler kullandım . Bir örnek, foreach
sahne arkasındaki veriler çeşitli dosya akışları ve serileştirmeler kullanılarak toplansa da , bir döngü içinde bir dizi nesne sağlayan bir veri akışı işleme kütüphanesidir .
Müşteri kodu
foreach(var item in feed.GetItems())
Console.WriteLine(item);
Kütüphane
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;
}
}
Gerçekte uygulama IEnumerable
, nesnenin tekrarlanabileceği anlamına gelir. Bu, dizine eklenemeyen belirli listeler olduğu için bir dizi olduğu anlamına gelmez, ancak bunları numaralandırabilirsiniz.
IEnumerator
yinelemeleri gerçekleştirmek için kullanılan gerçek nesnedir. Listedeki bir nesneden diğerine geçmeyi kontrol eder.
Çoğu zaman, IEnumerable
& IEnumerator
bir foreach
döngünün parçası olarak şeffaf bir şekilde kullanılır .
IEnumerable ve IEnumerator arasındaki farklar:
IEnumerable koleksiyonunu başka bir işleve geçirdiğimizde, öğenin / nesnenin geçerli konumunu bilmiyor (hangi öğeyi yürüttüğünü bilmiyor)
IEnumerable bir yöntem GetEnumerator () var
public interface IEnumerable<out T> : IEnumerable { IEnumerator<T> GetEnumerator(); }
IEnumerator, Current adlı iki özelliğe ve Reset () ve MoveNext () yöntemine sahiptir (bu, listedeki bir öğenin geçerli konumunu bilmek için yararlıdır).
public interface IEnumerator
{
object Current { get; }
bool MoveNext();
void Reset();
}
IEnumerable, Ienumerator içeren bir kutudur. IEnumerable tüm koleksiyonlar için temel arayüzdür. toplama IEnumerable uygularsa foreach döngüsü çalışabilir. Aşağıdaki kodda, kendi Numaralandırıcıya sahip olma adımını açıklar. İlk olarak koleksiyonunu yapacağımız Sınıfımızı tanımlayalım.
public class Customer
{
public String Name { get; set; }
public String City { get; set; }
public long Mobile { get; set; }
public double Amount { get; set; }
}
Şimdi Sınıf Müşterimiz için bir koleksiyon görevi görecek olan Sınıfı tanımlayacağız. IEnumerable arabirimini uyguladığına dikkat edin. Böylece GetEnumerator yöntemini uygulamak zorundayız. Bu, özel Numaralandırıcımızı döndürecektir.
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);
}
}
Şimdi aşağıdaki gibi kendi özel Sayımcımızı oluşturacağız. Bu nedenle, MoveNext yöntemini uygulamalıyız.
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.
}
}
Şimdi foreach döngüsünü koleksiyonumuz üzerinde aşağıdaki gibi kullanabiliriz;
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();
}
}
Yineleyici modelini anlamak sizin için yararlı olacaktır. Ben de aynısını okumanızı tavsiye ederim.
Yüksek seviyede yineleyici deseni, herhangi bir tipteki koleksiyonlar yoluyla standart bir yineleme yöntemi sağlamak için kullanılabilir. Yineleyici modelinde, gerçek koleksiyonda (istemci), toplayıcıda ve yineleyicide 3 katılımcı var. Toplama, yineleyici döndüren bir yöntemi olan bir arabirim / soyut sınıftır. Yineleyici, bir koleksiyon üzerinden yineleme yapmamıza izin veren yöntemlere sahip bir arabirim / soyut sınıftır.
Deseni uygulamak için, önce ilgili koleksiyon (istemci) üzerinde tekrar edebilen bir beton üretmek için bir yineleyici uygulamamız gerekir. Daha sonra toplama (istemci) yukarıdaki yineleyicinin bir örneğini döndürmek için toplayıcıyı uygular.
Yani temelde c #, IEnumerable soyut toplama ve IEnumerator soyut Iterator olduğunu. IEnumerable, istenen türde bir IEnumerator örneği oluşturmaktan sorumlu tek bir GetEnumerator yöntemine sahiptir. Listeler gibi koleksiyonlar IEnumerable uygulamasını uygular.
Misal. Biz bir yöntem olduğunu varsayalım Sağlar getPermutations(inputString)
bir dize ve döner tüm permütasyon yöntemi bir örneğini döndürürIEnumerable<string>
Permütasyon sayısını saymak için aşağıdaki gibi bir şey yapabiliriz.
int count = 0;
var permutations = perm.getPermutations(inputString);
foreach (string permutation in permutations)
{
count++;
}
C # derleyicisi aşağı yukarı yukarıdakileri
using (var permutationIterator = perm.getPermutations(input).GetEnumerator())
{
while (permutationIterator.MoveNext())
{
count++;
}
}
Herhangi bir sorunuz varsa lütfen sormaktan çekinmeyin.
Küçük bir katkı.
Birçoğunun 'ne zaman kullanılacağını' ve 'foreach ile kullan'ı açıkladığı gibi. Burada hem IEnumerable hem de IEnumerator arasındaki fark hakkında soruda istendiği gibi Başka Durumlar Farkı eklemeyi düşündüm .
Aşağıdaki tartışma örnekleri dayalı aşağıdaki kod örneği oluşturdu.
IEnumerable, IEnumerator vs foreach, ne zaman kullanılır IEnumerator ve IEnumerable arasındaki fark nedir?
Numaralandırıcı diğer numaralar yinelendiğinde işlev çağrıları arasındaki durumu (yineleme konumu) korur.
İşte anlamak için yorumlarla test örneği.
Uzmanlar lütfen beni ekleyin / düzeltin.
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());
}
}
Bu farkları fark ettim:
C. Listeyi farklı bir şekilde yineliyoruz, foreach IEnumerable için ve while döngüsü IEnumerator için kullanılabilir.
B. Bir yöntemden diğerine geçtiğimizde IEnumerator geçerli dizini hatırlayabilir (geçerli dizinle çalışmaya başlar), ancak IEnumerable dizini hatırlayamaz ve dizini başlangıca sıfırlar. Bu videoda daha fazlası https://www.youtube.com/watch?v=jd3yUjGc9M0
IEnumerable
ve IEnumerator
her ikisi de C # 'daki arayüzlerdir.
IEnumerable
bir arabirim GetEnumerator()
döndüren tek bir yöntemi tanımlayan bir IEnumerator
arabirimdir.
Bu, bir deyimle IEnumerable
kullanılabilen bir koleksiyona salt okunur erişim için çalışır foreach
.
IEnumerator
iki yöntemi vardır MoveNext
ve Reset
. Ayrıca adlı bir özelliği vardır Current
.
Aşağıda IEnumerable ve IEnumerator'ın uygulanması gösterilmektedir.
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
*/