Anasayfa / C# / CONSOLE APPS / C# foreach Döngüsü: Diziler ve Koleksiyonlarda

C# foreach Döngüsü: Diziler ve Koleksiyonlarda

C# programlama eğitim serimizde, programlarımıza tekrar eden işlemleri yaptırmayı sağlayan döngüler (loops) konusuna devam ediyoruz. Önceki rehberlerimizde, belirli bir sayıda tekrar eden işlemler için for döngüsünü, belirli bir koşul sağlandığı sürece çalışan işlemler için ise while döngüsünü öğrenmiştik.

Şimdi ise yazılım geliştiricilerin günlük hayatta, özellikle veri listeleriyle çalışırken en çok kullandığı, yazımı en kolay ve okunabilirliği en yüksek döngüye geldik: C# foreach Döngüsü.

Eğer bir e-ticaret sitesindeki ürünleri ekranda listelemek, bir sınıftaki öğrencilerin notlarını tek tek okumak veya kullanıcının sepetindeki ürünlerin toplam fiyatını hesaplamak istiyorsanız, foreach döngüsü sizin en yakın arkadaşınız olacaktır. Bu bol örnekli rehberimizde, C# foreach döngüsünün yapısını, for döngüsünden farklarını ve dikkat etmeniz gereken önemli kuralları sıfırdan öğreneceğiz.


1. foreach Döngüsü Nedir?

İngilizce “for each” kelimeleri, Türkçe’de “her biri için” anlamına gelir. foreach döngüsü, bir dizi (array) veya koleksiyon (collection) içindeki elemanların her biri için teker teker çalışan özel bir döngü türüdür.

Bir for veya while döngüsünde sayacın (örneğin i değişkeni) kaçtan başlayacağını, kaça kadar gideceğini ve kaçar kaçar artacağını biz belirleriz. Ancak foreach döngüsünde bir sayaca veya bitiş koşuluna ihtiyacınız yoktur. Döngü, verdiğiniz listenin ilk elemanından otomatik olarak başlar ve son elemanına kadar sırayla tüm verileri size getirir. Liste bittiğinde ise döngü kendiliğinden sona erer.

Günlük Hayattan Bir Analoji: Bir fotoğraf albümüne baktığınızı hayal edin. Albümü açarsınız ve ilk fotoğraftan başlayarak son fotoğrafa kadar her birine tek tek bakarsınız. İşte foreach döngüsünün yaptığı iş tam olarak budur; dijital albümünüzdeki (dizinizdeki) her bir veriye sırayla odaklanmanızı sağlar.


2. foreach Döngüsünün Anatomisi (Sözdizimi)

Bir foreach döngüsü yazarken 4 temel bileşene ihtiyaç duyarız:

foreach (VeriTipi DegiskenAdi in KoleksiyonAdi)
{
    // Her bir eleman için yapılacak işlemler
}

  • VeriTipi: Koleksiyonun içindeki verilerin tipi (Örn: string, int, double). Modern C# ile buraya doğrudan var da yazabilirsiniz; sistem tipi otomatik algılar.
  • DegiskenAdi: Döngü her döndüğünde, o anki elemanı temsil edecek olan geçici isim (örneğin urun, isim, sayi).
  • in: C# diline özgü, “içinde” anlamına gelen ve koleksiyonu işaret eden anahtar kelime.
  • KoleksiyonAdi: Üzerinde gezineceğimiz, önceden tanımlanmış dizi veya listenin adı.

3. İlk foreach Döngümüz: Şehirleri Listelemek

Önceki derslerimizde öğrendiğimiz Top-level statements (Üst düzey ifadeler) pratikliğini kullanarak ilk örneğimizi yazalım. Bir metin (string) dizisi oluşturalım ve içindeki şehirleri ekrana yazdıralım.

// İçinde 4 adet şehir bulunan bir string dizisi (array) oluşturuyoruz.
string[] sehirler = { "İstanbul", "Ankara", "İzmir", "Antalya" };

Console.WriteLine("Türkiye'nin Büyük Şehirleri:");
Console.WriteLine("----------------------------");

// sehirler dizisinin içindeki her bir 'sehir' için bu döngüyü çalıştır.
foreach (string sehir in sehirler)
{
    Console.WriteLine(sehir);
}

Bu kod nasıl çalışır?

  1. Bilgisayar foreach satırına gelir ve sehirler dizisinin içine bakar.
  2. İlk eleman olan “İstanbul”u alır ve geçici sehir değişkeninin içine kopyalar. Süslü parantezlerin içindeki kod çalışır ve ekrana “İstanbul” yazar.
  3. Başa döner, ikinci eleman olan “Ankara”yı alır, sehir değişkenine kopyalar ve ekrana yazar.
  4. Dizi bitene kadar bu işlem devam eder. Son elemandan sonra döngü güvenli bir şekilde, hiçbir hata vermeden sonlanır.

4. for Döngüsü vs. foreach Döngüsü

Neden for yerine foreach kullanmalıyız? Aynı işlemi for döngüsü ile yapsaydık kodumuz şu şekilde görünürdü:

string[] meyveler = { "Elma", "Armut", "Muz" };

// for döngüsü ile:
for (int i = 0; i < meyveler.Length; i++)
{
    Console.WriteLine(meyveler[i]);
}

// foreach döngüsü ile:
foreach (var meyve in meyveler)
{
    Console.WriteLine(meyve);
}

Farklar ve Avantajlar:

  • Okunabilirlik: foreach çok daha sade ve İngilizce bir cümle okur gibi anlaşılırdır (“for each meyve in meyveler”).
  • Güvenlik (Index Hataları): for döngüsünde i <= meyveler.Length yazarsanız, dizi sınırlarını aşacağınız için programınız çöker (IndexOutOfRangeException hatası). foreach döngüsünde ise sınırları bilgisayar kendisi yönettiği için sınır aşımı hatası yapmanız imkansızdır.
  • foreach kullanırken arka planda dizi boyutunu hesaplamakla veya indeks numaralarıyla ([i]) uğraşmak zorunda kalmazsınız.

5. Gerçek Hayat Senaryosu: Alışveriş Sepeti Toplamı

Biraz daha matematiksel bir örnek yapalım. Bir e-ticaret sitesinde kullanıcının sepetindeki ürünlerin fiyatlarını tutan bir dizimiz olsun. foreach kullanarak sepetteki toplam tutarı hesaplayalım:

// Sepetteki ürünlerin fiyatları (Ondalıklı sayılar için double kullanıyoruz)
double[] sepetFiyatlari = { 150.50, 45.00, 299.99, 15.75 };

double toplamTutar = 0;

// Sepetteki her bir fiyatı alıp toplamTutar değişkeninin üzerine ekliyoruz
foreach (double fiyat in sepetFiyatlari)
{
    toplamTutar += fiyat; // += operatörünü hatırlayın: toplamTutar = toplamTutar + fiyat;
}

Console.WriteLine($"Sepetinizdeki 4 ürünün toplam tutarı: {toplamTutar} TL");

Bu sayede dizi içerisinde 4 değil 4000 tane fiyat olsaydı bile, sadece tek bir foreach döngüsü ile milisaniyeler içinde tüm muhasebeyi yapabilirdik.


6. C# 9 ve Sonrası İçin ‘var’ Anahtar Kelimesinin Gücü

Değişkenler konumuzda var anahtar kelimesini öğrenmiştik. foreach döngüsü yazarken, koleksiyonun içindeki verinin tipini uzun uzun yazmak yerine doğrudan var kullanmak modern C# dünyasında en yaygın yaklaşımdır.

int[] sayilar = { 10, 20, 30, 40, 50 };

// 'int' yazmak yerine 'var' yazıyoruz. C# dizinin int olduğunu bildiği için
// 'sayi' değişkeninin int olması gerektiğini otomatik olarak anlar.
foreach (var sayi in sayilar)
{
    Console.WriteLine(sayi * 2); // Sayıların iki katını ekrana yazdırıyoruz
}


7. foreach Döngüsünün İki Altın Kuralı (Kısıtlamalar)

foreach döngüsü harikadır ancak bilmeniz ve asla unutmamanız gereken iki önemli kısıtlaması (kuralı) vardır:

Kural 1: foreach Döngüsü Salt Okunurdur (Read-Only) foreach döngüsü içinde tanımladığınız yineleyici değişken (bizim örneğimizdeki sehir veya fiyat), dizideki elemanın sadece bir kopyasıdır/okunabilir halidir. Döngü içindeyken bu değişkene yeni bir değer atayamazsınız.

string[] renkler = { "Kırmızı", "Mavi", "Yeşil" };

foreach (var renk in renkler)
{
    // renk = "Sarı"; // HATA! foreach içindeki değişkene atama yapılamaz.
    Console.WriteLine(renk);
}

Eğer dizinin içindeki verileri değiştirmek istiyorsanız, indeks numaralarına ihtiyaç duyacağınız için mecbur for döngüsü kullanmalısınız.

Kural 2: Döngü Sırasında Koleksiyonun Boyutu Değiştirilemez Bir koleksiyonun üzerinde foreach ile gezinirken, o koleksiyona yeni bir eleman ekleyemez veya var olan bir elemanı silemezsiniz. Eğer bunu yapmaya çalışırsanız C# çalışma zamanında (Runtime) uygulamanızı durdurur ve anında InvalidOperationException (Koleksiyon değiştirildi) hatası fırlatır.


Sonuç ve Sonraki Adımlar

Tebrikler! C# programlamanın en şık ve en çok tercih edilen veri okuma yapısı olan foreach döngüsünü tüm detaylarıyla öğrendiniz. Artık elinizdeki verilerin for ile indeks numaralarını saymadan, güvenli ve hızlı bir şekilde ekrana yazdırabilecek, veriler üzerinde matematiksel işlemler (toplama, ortalama alma vb.) yapabileceksiniz.

Şu ana kadar gördüğümüz örneklerde verileri hep { "A", "B", "C" } şeklinde basit dizilerde (arrays) tuttuk. Ancak gerçek dünyada veri listeleri sürekli büyür ve küçülür. İşte bu yüzden bir sonraki konumuzda, foreach döngüsünün en iyi arkadaşı olan Gelişmiş Koleksiyonlar ve Listeler (List) yapısına geçiş yapacak ve verilerimizi çok daha profesyonel şekilde yöneteceğiz. Bol kodlamalı günler dileriz!

Etiketlendi:

Cevap bırakın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir