Menu
flag Ar iconالعربيةdown icon

break وcontinue وgoto في C#: مغادرة الحلقات والحلقات المتداخلة

كيف تعمل break وcontinue وgoto في C#: إنهاء الحلقة مبكرًا، وتخطي تكرار، وbreak داخل switch، وثلاث طرق للخروج من الحلقات المتداخلة (علامة، أو goto، أو دالة مع return)، وخطأ الحلقة اللانهائية بسبب continue داخل while.

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

تنهي break الحلقة مبكرًا. وتتخطى continue بقية التكرار الحالي وتنتقل إلى التالي. كلتاهما تنطبق على الحلقة المحيطة الأعمق، وتعملان بالطريقة نفسها في for وforeach وwhile وdo while.

المخرجات:

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 و-5. وأوقفت break الحلقة عند 999، فلم تُزر 60 أبدًا، واستُؤنف التنفيذ عند أول عبارة بعد الحلقة.

break: توقّف حين تُعرف الإجابة

الاستخدام النموذجي لـ break هو البحث: بمجرد أن تجد ما تبحث عنه لا داعي للنظر في البقية.

المخرجات:

first invalid email at index 1

لا يُنفَّذ المكرِّر (i++) بعد break، فلو صُرّح بـ i خارج الحلقة لظلت تحمل الفهرس المطابق. وللبحث البسيط يقول استدعاء من المكتبة الشيء نفسه: تعيد Array.FindIndex(emails, e => !e.Contains("@")) الفهرس (أو -1)، وتجيب emails.Any(e => !e.Contains("@")) في LINQ عن وجود بريد سيئ.

continue: التخطي إلى التكرار التالي

continue جملة حراسة للحلقات. بدل تغليف العمل الحقيقي في if، ارفض الحالات التي لا تريدها في الأعلى:

المخرجات:

pen costs 1.20
mug costs 8.00

إلى أين تذهب continue بعدها يعتمد على الحلقة. في حلقة for تنفّذ المكرِّر ثم تختبر الشرط. وفي حلقة while تقفز مباشرة إلى الشرط، وهذا يؤدي إلى خطأ تقليدي:

int i = 0;
while (i < 10)
{
    if (i % 2 == 0)
        continue;        // i++ below is skipped: i stays 0 forever
    Console.WriteLine(i);
    i++;
}

حدّث العدّاد قبل أي continue، أو استخدم حلقة for، حيث يعيش التحديث في الترويسة ويُنفَّذ دائمًا.

break داخل switch داخل حلقة

في switch تنهي break قسم الحالة. وحين تكون switch داخل حلقة فإن break تنتمي إلى switch لا إلى الحلقة:

المخرجات:

quit received
count = 2

كانت break عادية في حالة "quit" ستنهي switch فقط، وتستمر الحلقة، وتكون count مساوية لـ 3. تقفز goto إلى العنوان بعد الحلقة. ونقل الحلقة إلى دالة وكتابة return في تلك الحالة يعمل أيضًا ولا يحتاج إلى عنوان.

الخروج من الحلقات المتداخلة

لا توجد في C# جملة break بعنوان مثل break outer; في Java. حين يمرّ بحث عبر حلقتين متداخلتين تنهي break في الحلقة الداخلية الداخليةَ فقط؛ وتنتقل الحلقة الخارجية إلى صفها التالي. هناك ثلاثة حلول قياسية.

1. علامة تفحصها الحلقة الخارجية:

المخرجات:

first free seat: row 1, seat 2

2. goto إلى عنوان بعد الحلقتين. هذا هو الموضع الوحيد الذي تقبل فيه أدلة أسلوب C# كثيرة goto، لأنها تعبّر بالضبط عن "غادر الحلقتين":

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، وهي الأنظف عادة، لأن البحث يحصل على اسم ويمكنه إعادة نتيجته:

المخرجات:

first free seat: row 1, seat 2

قدّمت C# 7.0 أيضًا الدوال المحلية، التي تتيح لك وضع تلك الدالة المساعدة داخل الدالة المستدعية. ونمط معامل out المستخدم هنا مشروح في صفحة ref وout.

goto والعناوين

العنوان معرّف تليه نقطتان، وgoto label; تقفز إليه. القواعد صارمة بما يكفي لمنع أسوأ سوء استخدام:

  • يجب أن يكون العنوان في الدالة نفسها، في كتلة goto نفسها أو في كتلة محيطة بها. يمكنك القفز خارج الكتل لكن لا إلى داخل كتلة أبدًا: القفز من الخارج إلى عنوان داخل جسم حلقة هو الخطأ CS0159 (no such label within the scope of the goto statement).
  • لا يمكنك مغادرة كتلة finally بـ goto أو break أو continue.
  • داخل switch تنقل goto case 3; وgoto default; التحكم إلى قسم آخر. هكذا تعبّر switch في C# عن الانزلاق، لأن الانزلاق الضمني إلى الحالة التالية خطأ ترجمة.

يمكن لـ goto أيضًا بناء حلقات (بالقفز للخلف إلى عنوان)، لكن حلقة while تقول الشيء نفسه بشكل يعرفه كل قارئ. أبقِ goto لمغادرة الحلقات المتداخلة ولأقسام switch.

return وthrow والحلقات

تغادر return الدالة كلها، فتغادر أيضًا كل حلقة فيها. وتفعل throw الشيء نفسه برمي استثناء. داخل كتلة try معها finally ما زالت break وcontinue وgoto وreturn كلها تنفّذ كتلة finally قبل أن ينتقل التحكم، وهذا ما يجعل الخروج آمنًا من حلقة تُبقي ملفًا مفتوحًا في كتلة using.

العبارةما تغادرهأين يستمر التنفيذ
continueالتكرار الحاليالتكرار التالي (المكرِّر ثم الشرط)
breakالحلقة الأعمق أو switchالعبارة التي بعدها
goto labelأي كتل محيطةالعنوان
returnالدالةالمستدعي
throwكل شيء حتى catch مطابقةكتلة catch

الأسئلة الشائعة

ما الفرق بين break وcontinue في C#؟

تنهي break الحلقة الأعمق (أو switch) فورًا؛ ويستمر التنفيذ بعدها. أما continue فتنهي التكرار الحالي فقط وتقفز إلى التالي: في حلقة for يُنفَّذ المكرِّر بعدها، وفي while وdo while يُختبر الشرط بعدها، وفي foreach يُجلب العنصر التالي.

كيف أخرج من الحلقات المتداخلة في C#؟

لا توجد في C# جملة break بعنوان. الخيارات الثلاثة: اضبط علامة bool واختبرها في الحلقة الخارجية، أو اقفز فوق الحلقتين بـ goto إلى عنوان، أو انقل الحلقات إلى دالة واستخدم return. نسخة الدالة هي الأنظف عادة، لأنها تمنح البحث اسمًا وقيمة معادة أيضًا.

هل تخرج break داخل switch من الحلقة في C#؟

لا. داخل switch موجودة في حلقة، تنهي break قسم switch وتستمر الحلقة. لمغادرة الحلقة من داخل حالة استخدم return، أو علامة تُفحص بعد switch، أو goto إلى عنوان بعد الحلقة. أما continue داخل حالة فتذهب فعلًا إلى التكرار التالي للحلقة.

هل goto مسموحة في C#؟

نعم. تقفز goto label; إلى label: في الدالة نفسها، لكنها لا تستطيع القفز إلى داخل كتلة ولا الخروج من finally. وداخل switch تقفز goto case value; وgoto default; بين الأقسام. خارج مغادرة الحلقات المتداخلة والانزلاق الصريح في switch، نادرًا ما تكون goto الخيار الأوضح.

Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن