Merhaba
Yazılım geliştirme esnasında karşıma birçok kez çıkan bu arayüzlerin kullanımı ve mantıksal olarak çözümlenmesi konularına kendimce değinmek istiyorum.
Bu kavramlara gelmeden önce ilk olarak Iteration(yineleme) konusu üzerinde durmak gerekir sanırım.
Matematikte gördüğümüz fonksiyonlar, fibonacci serisi ve bunun gibi şeylerde mantıksal bir yöntem kullanılır. Yazılımda ise geçişler döngüler ve onun adımları ise itersayon ile açıklanmakta. Bu konuda daha fazla bilgi için linkten faydalanabilirsiniz.
Örnekler üzerinden gitmek daha iyi olacaktır sanırım.
Mesela foreach içerisinde List<int> tipinde oluşturulan dep1 örneğini kullandık. Bunda sıkıntı yok çünkü List sınıfı IEnumerable arayüzünden implemente edilmektedir, nedenine ileride değineceğim için şimdilik bu kısmı bilmemiz yeterli. Eğer ben farklı bir sınıf oluşturup onu foreach içerisinde kullanmak istersem ne yapmalıyım?
Foreach ile kullanılmak üzere kendi oluşturduğumuz bir sınıf olsun. Aşağıda buna bir örnek verebiliriz.
Yukarıdaki Calisan sınıfından oluşturduğumuz örneği foreach içerisinde kullanmak istersem;
Bu kullanımda alacağımız hata şu şekilde olacaktır.

Yukarıdaki hatada Calisan sınıfının bir GetEnumerator içermediğini belirtiyor. Yani buradan da şu çıkarımı yapabiliriz;
Örneğin oluşturduğumuz bir List içerisine biz Add komutu ile ekleme yapabiliyoruz veya Count ile içerisinde bulunan elemanların sayısını alabiliyoruz ve bunu foreach içerisinde kullanabiliyoruz. Peki List bir sınıf olmasına rağmen foreach nasıl buna izin veriyor?

Yukarıdaki List sınıfının implement aldığı arayüzleri incelersek IEnumerable arayüzünü de orada görmekteyiz.
Şimdi bu arayüz nasıl kullanılıyor bu kısıma geçelim.
Herhangi bir sınıf oluşturup IEnumerable arayüzünü implemente ettiğimizi düşünelim. Bu işlemi yapınca sınıfa GetEnumerator metodu implemente olmuş oldu. Bununla birlikte artık bu sınıfı foreach içerisinde de kullanabilirim. Aşağıdaki sınıfta yaptıklarımızı adım adım anlatmadan önce eğer bir sınıfa IEnumerator implemente edilirse hangi metotların implement olacağına değinmek istiyorum. Düzenlediğim haliyle aşağıdaki kod yapısını inceleyelim;
Eğer kendimiz implemente edilen metotları farklı şekilde düzenlemek istersek bu şekilde içerisini düzenleyebiliriz. Ancak normal akışında çalışmasını istersekte implemete edip aynı şekilde bırakırız. Bu metotların detaylı açıklamalarını aşağıda yapacağım. Aşağıda buna örnek verebiliriz.
- Current yinelemenin(iteration) nerede olduğunu temsil eder.
- MoveNext ile bool tipinde değer döndürerek sonraki index varmı diye kontrol yapılır.
- Reset metodu ile index = -1 yapılarak işlemler başa alınır.
Aşağıda Calisan ve Firma sınıflarını kullandığımız örnek ile devam edelim.
- Oluşturduğumuz constructor içerisinde params ile Calisan tipinde parametre girebileceğimi ve sayısının da belirsiz olduğunu belirttik. Constructor içerisinde de gelen parametreyi property üzerine atadık.
- ToplamCalisanSayisi() metodu ile eklediğim toplam çalışan sayısını öğrendim. Bu metodu Count() metoduna da benzetebiliriz.
- YasOrtalamasi property ile bir kapsülleme gerçekleştirdik, içerisinde ise IEnumerator tipinde sayac tanımladık ve buna TumCalisanlar.GetEnumerator’ı atadık. Buradaki GetEnumerator ise TumCalisanlar dizisi bir Array olduğundan dolayı gelmektedir. Array sınıfı da anlaşılacağı üzere IEnumerable arayüzünden implemente almaktadır.
- MoveNext() metodu ise görüldüğü üzere bool değer döndürmektedir. Yani bu metot ile index numarası arttırılıp dizinin boyutuna gelinip gelinmediğini öğreniriz. Farkettiyseniz foreach döngüsünün çalışma prensibini anlatır şekilde devam ediyorum çünkü arka planda foreach GetEnumerator ile bu şekilde çalışmaktadır. Bu şekilde ortalama yaşa da ulaşmış olduk.
- Son olarak ise implemente edilen GetEnumerator() metodu ile dönen değerin TumCalisanlar dizisinden geleceğini belirttik.
Bu işlemleri tamamladıktan sonra foreach içerisinde Firma sınıfını kullanmayı denersek hata vermeyecektir.
Şimdi gelelim IEnumerator kısmına;
Az önceki örnekte IEnumerator normal akışında çalışıyordu ancak bu arayüz ile gelen metotları override etmek istersem aşağıdaki şekilde yapabilirim.
Bu işlemleri de tamamladıktan sonra şimdi oluşturduğumuz bu kod yapısını kullanabiliriz.
Bu konuda benim söyleyeceklerim şimdilik bunlar. Eğer bu yazıda herhangi bir eksik bilgi veya kaçırdığım nokta olduğunu düşünürseniz her türlü fikri benimle de paylaşırsanız sevinirim.
Teşekkürler.