Memik Yanık - Kişisel Web Sitesi Ana Sayfa | Hakkımda | Kitap Önerileri | Fotoğraflarım | RSS RSS | İletişim

GetEnumerator Metodu


ArrayList sınıfı gibi koleksiyon sınıflarının çoğu IEnumerator arayüzünü uyguladığı için bu sınıfların GetEnumerator() metotları bulunmaktadır. Bu metot sayesinde söz konusu koleksiyon nesnesinin elemanlarını bir numaralayıcıya(enum) alıp bazı işlem­leri kolayca yapabilirsiniz. Bu metot hakkında bilgi vermek için Visual Studio ile hazırladığımız projede aşağıdaki gibi kod yazıp birkaç elemana sahip bir ArrayList nesnesi hazırladık. 

Dim
Liste As ArrayList
Private Sub Form1_Load(ByVal sender As System.Object, _
            ByVale As System.EventArgs) Handles MyBase.Load 
   Liste = New ArrayList(10
   Liste.Add("Hard Disk"
   Liste.Add("Yazıcı"
   Liste.Add("Ekran"
   Liste.Add("İşlemci"
   Liste.Add("Bellek"
   Liste.Add("Kasa")
EndSub 

ArrayList nesnesini Class’taki bütün metotlarda kullanabilmek için değişken tanımlamayı metot dışında yaptık. Bu şekilde ArrayList nesnesi hazırladıktan sonra ArrayList sınıfının GetEnumerator() metodundan yararlanıp
IEnumeratornesnesi hazırlayacağız. Bu amaçla yukarıda verilen koda ekleme yapıp IEnumerator nesnesi hazırladık. 

Dim
Liste As ArrayList
Dim enum_nesnesi As IEnumerator
Private Sub Form1_Load(ByVal sender As System.Object, _
        ByVale As System.EventArgs) Handles MyBase.Load 
   Liste = New ArrayList(10
   Liste.Add("Hard Disk"
   Liste.Add("Yazıcı"
   Liste.Add("Ekran"
   Liste.Add("İşlemci"
   Liste.Add("Bellek"
   Liste.Add("Kasa"
   enum_nesnesi = Liste.GetEnumerator()
EndSub 

Bu şekilde hazırlanan
IEnumerator tipindeki koleksiyonun elemanları üzerinde ileri doğru hareket edip elemanlarının içeriğini tek tek elde edebiliriz. Bu amaçla Visual Studio ile hazırladığımız Visual Basic uygulamasının formuna bir TextBox yerleştirip yukarıda verilen kodu aşağıdaki gibi düzenledik. 

Dim
Liste As ArrayList
Dim enum_nesnesi As IEnumerator
Private Sub Form1_Load(ByVal sender As System.Object, _
            ByVale As System.EventArgs) Handles MyBase.Load 
   Liste = New ArrayList(10
   Liste.Add("Hard Disk"
   Liste.Add("Yazıcı"
   Liste.Add("Ekran"
   Liste.Add("İşlemci"
   Liste.Add("Bellek"
   Liste.Add("Kasa"
   enum_nesnesi = Liste.GetEnumerator() 
   enum_nesnesi.MoveNext() 
   TextBox1.Text = enum_nesnesi.Current.ToString()
EndSub 

Bu kod sayesinde IEnumerator tipindeki koleksiyonun ilk elemanın içeriği TextBox’a aktarılır. Forma bir düğme yerleştirip MoveNext() metodunu tekrar işleterek koleksiyondaki bir sonraki elemanın üzerine gidip bu elemanın içeriğini elde edebilirsiniz. Bu işlemin nasıl yapıldığını aşağıda görebilirsiniz. 

Private
Sub sonraki_Click(ByVal sender As System.Object, _
        ByVale As System.EventArgs) Handles sonraki.Click 
  enum_nesnesi.MoveNext() 
  TextBox1.Text = enum_nesnesi.Current.ToString()
EndSub 

Koleksiyondaki en son elemanın üzerinde iken bu kod işletilirse 2. satır hataya neden olur. Bu hatanın önüne geçmek için MoveNext() metodunun geriye gönderdiği değerden yararlanılır. Koleksiyondaki bir sonraki elemanın üzerine gitmek üzere MoveNext() metodu işletildi­ğinde geriye False veya True gönderilir. Koleksiyonun en son elemanının üzerinde iken MoveNext metodu işletildiğinde hareket başarılı olamayacağı için MoveNext() geriye False gönderir. Bu nedenle MoveNext() metodunun geriye gönderdiği boolean sonuç aşağıdaki gibi kontrol edilip olası hataların önüne geçilir. 

Private
Sub sonraki_Click(ByVal sender As System.Object, _
            ByVale As System.EventArgs) Handles sonraki.Click 
  Dim Sonuc As Boolean 
  Sonuc = enum_nesnesi.MoveNext() 
  If Sonuc = True Then 
     TextBox1.Text = enum_nesnesi.Current.ToString() 
  Else      
    MessageBox.Show("Koleksiyonun son elemanın üzerindesiniz"
  End If
EndSub 

Elbette ArrayList nesnesinin elemanları üzerinde hareket edip istenen elemanın içeriğini elde etmek mümündür. Ancak GetEnumerator() metodu ile hazırlanan koleksiyonun üzerinde haraket etmek daha kolaydır. Koleksiyonun yani Enum nesnesinin üzerinde olunan geçerli elema­nın içeriği Current özelliği ile elde edilmektedir. GetEnumerator() metodu ile hazırlanan koleksiyonun ilk elemanın üzerine gidilmek isten­diğinde Reset() metodu aşağıdaki gibi kullanılmalıdır. 

enum_nesnesi.Reset() 

GetEnumerator
() metodu ile hazırlanan enum nesnesinin elemanlarının nasıl kullanıldığına farklı bir örnek olması için Visual Basic uygulamasının formuna 2 ListBox yerleştirdik. İlk ListBox’a tasarım anında bir futbol takımının adını aktardık.



Kullanıcı çalışma anında formdaki düğmeyi tıkladığında ilk ListBox’ın içeriği önce ArrayList nesnesine, oradan GetEnumerator() metodu ile hazırlanan enum tipine aktaracağız. En son olarak enum nesnesinin içeriğini formdaki 2. ListBox’a aktaracağız. Bu işlemi yapmak üzere naklet* adını verdiğimiz düğmenin Click olayını temsil eden metodu aşağıdaki gibi düzenledik. 

Private
Sub naklet_Click(ByVal sender As System.Object, _
            ByVale As System.EventArgs) Handles naklet.Click 
  Dim Takimlar As New ArrayList() 
  For Each takim As Object In ListBox1.Items
    Takimlar.Add(takim
  Next 
  Dim koleksiyon As IEnumerator 
  koleksiyon = Takimlar.GetEnumerator 
  While (koleksiyon.MoveNext()) 
    ListBox2.Items.Add(koleksiyon.Current.ToString()) 
  End While
EndSub 

Yukarıda işaret edildiği üzere .NET Framework ile gelen koleksiyon sınıflarının hemen hepsi
GetEnumerator() metoduna sahiptir. Bu metodun işlevinin iyi anlaşılması için şimdi bir Queue nesnesi hazırlayıp bu nesnenin mevcut elemanlarını GetEnumerator() metodu ile enum koleksiyonuna aktaracağız. Bu amaçla yukarıda hazırladığımız projedeki formdaki ListBox’lardan birisini silip “naklet” adlı düğmenin Click olayını temsil eden metodu aşağıdaki gibi düzenledik. Bu kod işletildiğinde Queue nesnesinin eleman sayısı değişmeden bütün elemanlar elde edilip ListBox’a aktarılır. 

Private
Sub naklet_Click(ByVal sender As System.Object, _
            ByVale As System.EventArgs) Handles naklet.Click 
   Dim Kuyruk As Queue 
   Kuyruk = New Queue(10
   Kuyruk.Enqueue("İlkbahar"
   Kuyruk.Enqueue("Yaz"
   Kuyruk.Enqueue("Sonbahar"
   Kuyruk.Enqueue("Kış"
   ListBox1.Items.Clear() 
   Dim enum_liste As System.Collections.IEnumerator 
   enum_liste = Kuyruk.GetEnumerator() 
   While (enum_liste.MoveNext()) 
     ListBox1.Items.Add(enum_liste.Current
   End While
EndSub 

GetEnumerator
() metodu hakkında bilgi verirken yukarıda yararlandığımız ArrayList ve Queue nesnelerinin elemanlarında yalnızca değer bilgileri tutulabilmektedir. Elinizde anahtar-değer şeklinde düzenlenmiş bilgileri içerebilen Hashtable gibi bir nesne varsa bu nesnenin içeriğini GetEnumerator() metodu ile IDictionaryEnumerator tipinde bir numaralayıcıya alabilirsiniz. Bu işlemin nasıl yapıldığını anlatmak için aşağıda verilen kodu yazdık. 

Dim
iller As New Hashtable()
Dim
Liste As IDictionaryEnumerator
Private Sub Form1_Load(ByVal sender As System.Object, _
            ByVale As System.EventArgs) Handles MyBase.Load 
  iller.Add("01", "Adana"
  iller.Add("06", "Ankara"
  iller.Add("07", "Antalya"
  iller.Add("16", "Bursa"
  iller.Add("33", "Mersin"
  iller.Add("34", "İstanbul"
  iller.Add("35", "İzmir"
  Liste = iller.GetEnumerator()
EndSub 

Bu kodda önce “Liste” adında ve IDictionaryEnumerator tipinde bir değişken tanımla­dık. Bu değişkeni diğer metotlarda kullanabilmek için formun Load olayını temsil eden metodunun dışında tanımladım ve GetEnumerator() metodu ile Hashtable nesnesinin içeriğini bu numaralayıcıya kopyala­dık. 

Bu hazırlıktan sonra bu numaralayıcıdan yararlanarak Hashtable nesnesinin anahtar-değer şeklinde düzenlenmiş içeriğine kolayca erişebilirsiniz. Proje çalıştırıldığında HashTable nesnesinin ilk elemanın anahtar ve değer bilgilerinin nasıl okunduğunu göstermek için forma 2 TextBox yerleştirip yukarıda verilen kodu aşağıdaki gibi düzenledik. 

Dim
iller As New Hashtable()
Dim Liste As IDictionaryEnumerator
Private Sub Form1_Load(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.Load 
   iller.Add("01", "Adana"
   iller.Add("06", "Ankara"
   iller.Add("07", "Antalya"
   iller.Add("16", "Bursa"
   iller.Add("33", "Mersin"
   iller.Add("34", "İstanbul"
   iller.Add("35", "İzmir"
   Liste = iller.GetEnumerator() 
   Liste.MoveNext() 
   TextBox1.Text = Liste.Key.ToString() 
   TextBox2.Text = Liste.Value.ToString()
EndSub 

GetEnumerator
() metoduyla hazırlanan enum nesnesinin elemanlarının üzerinde ileri doğru hareket edebilmek için forma “sonraki” adında bir düğme yerleştirip bu düğmenin Click olayını temsil eden metodu aşağıdaki gibi düzenledik. 

Private
Sub sonraki_Click(ByVal sender As System.Object, _
            ByVale As System.EventArgs) Handles sonraki.Click 
  Liste.MoveNext() 
  TextBox1.Text = Liste.Key.ToString() 
  TextBox2.Text = Liste.Value.ToString()
EndSub 

Formdaki düğme tıklanıp bu metot işletildiğinde numaralayıcının bir sonraki elemanın üzerinde gidilir ve Hashtable nesnesinden alınan anahtar bilgisi ilk TextBox’a, değer bilgisi ise 2. TextBox’a aktarılır. 

Hashtable nesnesinin ve dolayısıyla IDictionaryEnumerator tipindeki koleksiyonun son elemanında iken MoveNext() metodu işletilirse hata meydana gelmez ama Key ve Value özellikle­rinin içerikleri okunmak istendiğinde hata meydana gelir. Bunun önüne geçmek için yukarıda verilen kodu aşağıdaki gibi düzenledik. 

Private
Sub sonraki_Click(ByVal sender As System.Object, _
        ByVale As System.EventArgs) Handles sonraki.Click 
  If (Liste.MoveNext()) Then 
    TextBox1.Text = Liste.Key.ToString() 
    TextBox2.Text = Liste.Value.ToString() 
  End If
EndSub 

Tekrarlamak gerekirse; önce IDictionaryEnumerator tipinde bir değişken tanımladık ve GetEnumerator() metodundan yararlanıp Hashtable nesnesinin elemanlarını IDictionaryEnumerator tipindeki numaralayıcıya aktardık. Bu sayede HashTable nesnesinin mevcut elemanlarına kolayca erişim imkânı bulduk. MoveNext() metodu ile üzerine gidilen elemanın anahtar bilgisi Key ve değeri ise Value özelliğine aktarıldığı için bu bilgileri alıp istendiğimiz gibi kullandık. 

GetEnumerator() metodu ile hazırlanıp IDictionaryEnumerator tipindeki değişkene aktarı­lan enum tipinden(yani numaralayıcıdan) geçerli anahtar ve değer bilgilerini bir seferde okumak istiyorsanız Entry özelliğine bakabilirsiniz. Entry özelliğinin nasıl kullanıldığını anlatmak için forma 2 ListBox yerleştirip aşağıda verilen kodu yazdık. 

Private
Sub naklet_Click(ByVal sender As System.Object, _
        ByVale As System.EventArgs) Handles naklet.Click 
   While Liste.MoveNext() 
     ListBox1.Items.Add(Liste.Entry.Key.ToString()) 
     ListBox2.Items.Add(Liste.Entry.Value.ToString()) 
   End While
EndSub 

*bu makaleyi bundan birkaç yıl önce yazmış olsaydık bu button nesnesine “naklet” yerine alışkanlıklarımız gereği “aktar” adını verirdik. Aktar’ı button nesnesi adı olarak kullanmak bir süredir izne tabi olduğu, başka bir deyişle forma yerleştirilen düğmelere “aktar” adını verme hakkı programcılık kitapları yazan birisine ait olduğu için button nesnesine çaresiz “naklet” adını verdik.

VB.NET 29.04.2010 03:45:29

1 YORUM


YorumlarYorum Yaz
Ana Sayfa | Hakkımda | Kitap Önerileri | Fotoğraflarım | RSS | İletişim
Memik Yanık 2004-2009 © Tüm Hakları Saklıdır.
Hazırlayan www.semgoksu.com