IEnumerable ve IEnumerator Ara yüzleri ve Kullanımı

Yazar: Sinan BARAN
Kategori: .NET Framework
Eklenme Tarihi: 23.8.2009 21:59:06



Merhaba Arkadaslar bu makalemde sizlere IEnumerable, IEnumerator Interface yapılarından bahsedeceğim(Makale içerisinde Yield yapisina’da değineceğim)

        Merhaba Arkadaslar bu makalemde sizlere IEnumerable, IEnumerator Interface yapılarından bahsedeceğim(Makale içerisinde Yield yapisina’da değineceğim).

Öncelikle bu interface yapılarını birçok yerde gördük ama ne işe yarıyor neden bu ara yüzlere ihtiyaç duyarım ve nerelerde kullanabilirim? Hemen bu sorulara cevap bulalım.

Foreach döngüsü tüm liste elemanları içerisinde hareket edebiliyor.

Bazı Liste yapılarından.

ArrayList :

public class ArrayList : IList, ICollection, IEnumerable, Icloneable

List :

public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, Ienumerable

SortedList :

public class SortedList<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, Ienumerable


Evet, bu liste yapıları içerisinde Foreach yapısı kullanılabilir. Çünkü foreach yapısı bu liste içerisinde iterasyon sağlayabilir. iterasyonu IEnumarable ve GetEnumerator yapıları sağlıyor.



Şekildeki örnek üzerinden hareket edecek olursak.

   Foreach her liste içerisine girip bir item aldığında arka planda saklanan anlık indeks numarası 1,1 arttırılıyor. Bu sayede her döngü esnasında bir sonraki elemanın indeks numarası elde ediliyor.


MoveNext() Metodu ise bu Liste içerisindeki eleman kadar döngünün gerçekleşmesini sağlıyor. Bir nevi karar mekanizması.

Current()  Metodu indeks numarasının elde etmiş olduğu o anki değer yani foreach yapısının sahip olmuş olduğu değer.

Reset()  Metodu ise arttırılan indeks numarasının değeri 0’a indirgeniyor.

 

 

Birsey dikkatinizi çekmiştir umarım… MoveNext(),Current, Reset() gibi mekanizmayı sanki ben birlerlerde kullanıyor gibiyim. Hemen For ve Foreach döngülerini kiyasliyalim.

 

  string[] Elemanlar = { "Sinan", "BARAN", "Sakarya", "Bilgisayar", "Programcılıgı", "Bilgedam" };

 

            string AnlikDeger = string.Empty;

      

            for (int i = 0; i < Elemanlar.Length; i++)

            {

                AnlikDeger = Elemanlar[i];

            }

 

       For dongusu ile bir liste icerisinde donmek icin,


  • Baslangic Degeri(int i = 0)

  • Karar Mekanizmasi (i < Elemanlar.Length)

  • Artis Miktari (i++)

Gibi Degerleri Vermek Zorundayiz.döngünün liste icerisinde hareket edebilmesi ve tüm elemanlari sırasi ile elde edebilmek icin.


     foreach (string item in Elemanlar)

            {

                AnlikDeger = item;

            }

Evet foreach yapısına bakıyoruz.

Foreach  Benden sadece hangi liste icerisinde dönmegi gerektigini yani hedefi istiyor.Geri kalani baslangic Degeri,Artis Miktari,Karar Mekanizmasi gibi özellikleri IEnumerable ve IEnumerator Interface’leri sağlıyor.

İste bahsetmiş oldugmuz durum’da bu ya. Liste yapıları IEnumerable ve IEnumerator’den implements edilerek oluşturuluyor. Yani bu yapı kendi içerisinde iterasyon yani hareket kabiliyeti oluşturuyor. Foreach bu yapıyı kullanarak çok rahat bir şekilde liste elemanları içerisinde hareket ederek bizlere bilgileri ulaştırabiliyor.

Kendi tiplerimiz ile olusturdugmuz listeleride IEnumerable ve IEnumerator Interface’lerden implements edersek Foreach yapısına kucak açmış oluruz.

Simdi örnek yapılara geçerek bu işi daha iyi bir şekilde çözebiliriz.

 public class Personel

    {

        public string Ad { get; set; }

        public string Soyad { get; set; }

 

        public Personel() { }

       

        public Personel(string ad, string soyad)

        {

            this.Ad = ad;

            this.Soyad = soyad;

        }

    }

 ------------------------------------------

    public class PersoneList

    {

        List<Personel> list = new List<Personel>();

        public void Ekle(Personel p)

        {

            list.Add(p);

        }

        public void Ekle(string ad, string soyad)

        {

            list.Add(new Personel(ad, soyad));

        }

    }


------------------------------------------

            PersoneList list = new PersoneList();

            list.Ekle("Sinan", "BARAN");

            list.Ekle("Ibrahim", "BARAN");

            list.Ekle("Murat", "BARAN");

            list.Ekle("Ramazan", "BARAN");

            list.Ekle("Muharrem", "BARAN");

            list.Ekle("Aydın", "BARAN");

            list.Ekle("Fatih", "BARAN");

            list.Ekle("Gokhan", "BARAN");

            list.Ekle("Hakan", "BARAN");

 

            foreach (Personel item in list)

            {

                listBox1.Items.Add(item.Ad + " " + item.Soyad);

            }

 

             Evet Bu yapi Kullanilmak istendiginde bana direk olarak hareket edebilecek alan bilgilerinin olmadigini bildirecek GetEnumerator()

O yuzden PersonelList yapisini IEnumerable yapı ile implements edeceğim.


    public class PersoneList : IEnumerable

    {

        List<Personel> list = new List<Personel>();

        public void Ekle(Personel p)

        {

            list.Add(p);

        }

        public void Ekle(string ad, string soyad)

        {

            list.Add(new Personel(ad, soyad));

        }

        public IEnumerator GetEnumerator()

        {

            return new PersonelEnumerator(list);

        }

    }


Daha Sonra Ienumerator Interface yapısını kullanan yani hareket kabiliyeti sunan Interface Yapısı Ienumerator

 

public class PersonelEnumerator : IEnumerator

    {

        public List<Personel> listem = new List<Personel>();

        int CurrentLocation = -1;

        public PersonelEnumerator(List<Personel> p)

        {

            this.listem = p;

        }

        public object Current

        {

            get

            {

                return this.listem[CurrentLocation];

            }

        }

        public bool MoveNext()

        {

            CurrentLocation++;

            return (CurrentLocation < this.listem.Count);

        }

 

        public void Reset()

        {

            CurrentLocation = -1;

        }

    }

 

Evet Ornek yapiyi indirebilir daha iyi bir sekilde irdeliyebilirsiniz.Yield Kullanimi ise Ienumerator Interface’sine ihtiyac duymaksizin benim iterasyonu sagliyan bir yapi


        List<Personel> list = new List<Personel>();

        public void Ekle(Personel p)

        {

            list.Add(p);

        }

        public void Ekle(string ad, string soyad)

        {

            list.Add(new Personel(ad, soyad));

        }

        public IEnumerator GetEnumerator()

        {

            foreach (Personel item in list)

            {

                yield return item;

            }

        }

Döngü her geldiginde kaldigi yerden devam ediyor.Aslinda Ienumerator yapısına göre daha performanslı bir özelliktir.Tabi Mekanizma icerisinde fazladan kontrol yapmıyacaksan.

IEnumarable_Interface_Yapisi_yield.rar (81,88 kb)

sinan.baran@bilgeadam.com
www.sinanbaran.com



Sinan BARAN

Sinan BARAN 2007 yılından itibaren .Net teknolojisi ile çalışmalarda bulunmaktadır.Birçok  orta ve ileri düzey projelerde yeralmıştır.Sinan BARAN şu anda BilgeAdam Bilgi Teknolojileri Akademisinde Yazilim Eğitmeni olarak çalişmaktadır.

Ahmet Burak Demirkoparan - 20.5.2012
Teşekkür ederim öğrenci arkadaştan not almıştım fakat çoğu şeyi yanlış yazmış mesela Ienumerator interfacesi yerine yine ienumerable felan implement etmiş beni baya uğraştırdı bu kaynağa bakıp sorunumu 2dk da çözdüm.Makaleniz için teşekkürler.

ayhan kara - 22.11.2011
Makale çok güzel emeğinize sağlık. Ama madde madde açıklamalara daha da yer verilse daha da yararlı olabileceğine inanıyorum.

Yorumunuz