break bir döngüyü erken bitirir. continue geçerli yinelemenin geri kalanını atlar ve bir sonrakine geçer. İkisi de en içteki çevreleyen döngüye uygulanır ve for, foreach, while ve do while'da aynı şekilde çalışır.
Çıktı:
process order of 45
skip invalid total 0
process order of 120
skip invalid total -5
process order of 80
test order found, stopping
after the loop
continue, 0 ve -5 için işleme satırının üzerinden atladı. break döngüyü 999'da durdurdu, bu yüzden 60 hiç ziyaret edilmedi ve çalışma döngüden sonraki ilk ifadeden devam etti.
break: Cevap Bilindiğinde Durmak
break'in tipik kullanımı bir aramadır: aradığınızı bulduğunuzda geri kalanına bakmanın bir nedeni yoktur.
Çıktı:
first invalid email at index 1
Yineleyici (i++) bir break'ten sonra çalışmaz, bu yüzden döngünün dışında bildirilmiş olsaydı i hâlâ eşleşen indeksi tutardı. Basit aramalar için bir kütüphane çağrısı aynı şeyi söyler: Array.FindIndex(emails, e => !e.Contains("@")) indeksi (ya da -1) döndürür ve LINQ'in emails.Any(e => !e.Contains("@"))'i hatalı bir tane olup olmadığını cevaplar.
continue: Sonraki Yinelemeye Atlamak
continue, döngüler için bir koruma cümlesidir. Asıl işi bir if'in içine sarmak yerine istemediğiniz durumları en başta reddedin:
Çıktı:
pen costs 1.20
mug costs 8.00
continue'nun ardından nereye gidildiği döngüye bağlıdır. Bir for döngüsünde yineleyiciyi çalıştırır ve sonra koşulu test eder. Bir while döngüsünde doğrudan koşula atlar; bu da klasik bir hataya yol açar:
int i = 0;
while (i < 10)
{
if (i % 2 == 0)
continue; // i++ below is skipped: i stays 0 forever
Console.WriteLine(i);
i++;
}
Sayacı herhangi bir continue'dan önce güncelleyin ya da güncellemenin başlıkta yaşadığı ve her zaman çalıştığı bir for döngüsü kullanın.
Döngü İçindeki switch'te break
Bir switch'te break case bölümünü bitirir. O switch bir döngünün içindeyse break döngüye değil switch'e aittir:
Çıktı:
quit received
count = 2
"quit" case'indeki düz bir break yalnızca switch'i bitirir, döngü devam eder ve count 3 olurdu. goto döngüden sonraki etikete atlar. Döngüyü bir metoda taşıyıp o case'te return yazmak da çalışır ve etiket gerektirmez.
İç İçe Döngülerden Çıkmak
C#'ta Java'nın break outer;'ı gibi etiketli bir break yoktur. Bir arama iç içe iki döngüden geçtiğinde iç döngüdeki bir break yalnızca içtekini bitirir; dış döngü sonraki satıra geçer. Üç standart çözüm vardır.
1. Dış döngünün kontrol ettiği bir bayrak:
Çıktı:
first free seat: row 1, seat 2
2. İki döngüden sonraki bir etikete goto. Birçok C# stil kılavuzunun goto'yu kabul ettiği tek yer burasıdır, çünkü tam olarak "iki döngüden de çık" demektir:
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
if (seats[row, col] == 0)
{
Console.WriteLine($"first free seat: row {row}, seat {col}");
goto done;
}
}
}
done:
Console.WriteLine("search finished");
3. return içeren bir metot. Genellikle en temizidir, çünkü arama bir ad alır ve sonucunu döndürebilir:
Çıktı:
first free seat: row 1, seat 2
C# 7.0 ayrıca o yardımcı metodu çağıran metodun içine koymanızı sağlayan yerel fonksiyonları getirdi. Burada kullanılan out parametresi kalıbı ref ve out sayfasında açıklanır.
goto ve Etiketler
Etiket, ardından iki nokta gelen bir tanımlayıcıdır ve goto label; ona atlar. Kurallar en kötü kötüye kullanımı önleyecek kadar katıdır:
- Etiket aynı metotta,
gotoile aynı blokta ya da çevreleyen bir blokta olmalıdır. Bloklardan dışarı atlayabilirsiniz ama asla bir bloğun içine atlayamazsınız: dışarıdan bir döngü gövdesinin içindeki bir etikete atlamak CS0159 hatasıdır (no such label within the scope of the goto statement). - Bir
finallybloğundangoto,breakya dacontinueile çıkamazsınız. - Bir
switchiçindegoto case 3;vegoto default;kontrolü başka bir bölüme aktarır. Bir sonraki case'e örtük olarak düşmek bir derleme hatası olduğundan, bir C# switch düşüşü böyle ifade eder.
goto döngü de kurabilir (bir etikete geri atlayarak), ama bir while döngüsü aynı şeyi her okuyucunun tanıdığı bir biçimde söyler. goto'yu iç içe döngülerden çıkmak ve switch bölümleri için saklayın.
return, throw ve Döngüler
return tüm metottan çıkar, dolayısıyla içindeki her döngüden de çıkar. throw bir istisna fırlatarak aynısını yapar. finally içeren bir try bloğunun içinde break, continue, goto ve return'ün hepsi kontrol ilerlemeden önce finally bloğunu yine de çalıştırır; using bloğunda açık bir dosya tutan bir döngüden çıkmayı güvenli kılan budur.
| İfade | Çıktığı yer | Devam ettiği yer |
|---|---|---|
continue | geçerli yineleme | sonraki yineleme (yineleyici, sonra koşul) |
break | en içteki döngü ya da switch | ondan sonraki ifade |
goto label | çevreleyen herhangi bir blok | etiket |
return | metot | çağıran |
throw | eşleşen bir catch'e kadar her şey | catch bloğu |
Sıkça Sorulan Sorular
C#'ta break ile continue arasındaki fark nedir?
break en içteki döngüyü (ya da switch'i) hemen bitirir; çalışma ondan sonra devam eder. continue yalnızca geçerli yinelemeyi bitirir ve sonrakine atlar: bir for döngüsünde ardından yineleyici çalışır, while ve do while'da ardından koşul test edilir, foreach'te sonraki eleman alınır.
C#'ta iç içe döngülerden nasıl çıkılır?
C#'ta etiketli break yoktur. Üç seçenek şunlardır: bir bool bayrağı ayarlayıp dış döngüde test etmek, goto ile iki döngünün de ötesindeki bir etikete atlamak ya da döngüleri bir metoda taşıyıp ondan return etmek. Metot sürümü genellikle en temiz olanıdır, çünkü aramaya bir ad ve bir dönüş değeri de verir.
C#'ta switch içindeki break döngüden çıkar mı?
Hayır. Bir döngüdeki switch'in içinde break switch bölümünü bitirir ve döngü devam eder. Bir case'in içinden döngüden çıkmak için return, switch'ten sonra kontrol edilen bir bayrak ya da döngüden sonraki bir etikete goto kullanın. Bir case içindeki continue ise döngünün sonraki yinelemesine gider.
C#'ta goto kullanılabilir mi?
Evet. goto label; aynı metottaki label:'a atlar, ama bir bloğun içine atlayamaz ya da bir finally'den çıkamaz. Bir switch içinde goto case value; ve goto default; bölümler arasında atlar. İç içe döngülerden çıkmak ve açık switch düşüşü dışında goto nadiren en anlaşılır seçimdir.