C# รองรับ **4 ประเภทของ Loop** สำหรับควบคุมการทำงานซ้ำ (Iteration) แต่ละแบบมีจุดมั่นและใช้งานเหมาะสมต่างกัน
1. while Loop - ตรวจสอบเงื่อนไขก่อน (Pre-test)
while (condition) {
// Body - รันก็ต่อเมื่อ condition เป็น true
}
- ตรวจสอบเงื่อนไข **ก่อน** เข้าลูป
- อาจ **ไม่รันเลย** ถ้าเงื่อนไข False ตั้งแต่แรก
- เหมาะกับ: ไม่ทราบจำนวนรอบแน่นอน, ขึ้นอยู่กับ External Condition
ตัวอย่าง
int count = 0;
while (count < 5) {
Console.WriteLine(count);
count++;
}
// Output: 0 1 2 3 4
2. for Loop - นับรอบ (Counter-controlled)
for (init; condition; increment) {
// Body
}
- มี 3 ส่วน: **Initialization**, **Condition**, **Increment/Decrement**
- เหมาะกับ: **ทราบจำนวนรอบล่วงหน้า**, ต้องการ Index/Count
- Scope ของ Variable ใน init อยู่ใน Loop เท่านั้น
ตัวอย่าง
// Standard
for (int i = 0; i < 10; i++) {
Console.WriteLine(i);
}
// Multiple Variables
for (int i = 0, j = 10; i < j; i++, j--) {
Console.WriteLine($"{i}, {j}");
}
// Infinite Loop
for (;;) { /* ... */ }
3. do-while Loop - ตรวจสอบเงื่อนไขท้าย (Post-test)
do {
// Body - รัน **อย่างน้อย 1 ครั้ง** เสมอ
} while (condition);
- รัน Body **ก่อน** ตรวจสอบเงื่อนไข
- รับประกันว่ารัน **อย่างน้อย 1 รอบ**
- เหมาะกับ: Menu Systems, Input Validation, Prompt User
ตัวอย่าง
int a = 50;
do {
Console.WriteLine("Value of a: " + a); // รัน 1 ครั้งแม้ a >= 20
a++;
} while (a < 20);
// Output: Value of a: 50
4. foreach Loop - Iterate Collections (C# 1.0+)
foreach (Type item in collection) {
// Body - item เป็น Read-only (ไม่สามารถ Assign ได้)
}
- ใช้กับ **IEnumerable/IEnumerable<T>** (Array, List, Dictionary, Custom Collections)
- **Read-only** - ไม่สามารถ Assign ให้
item ได้
- ไม่เข้าถึง Index ได้โดยตรง (ใช้
Select((item, index) => ...) หรือ for แทน)
- Compiler เรียก
GetEnumerator() และ MoveNext() อัตโนมัติ
ตัวอย่าง
int[] n = new int[10];
for (int i = 0; i < 10; i++) n[i] = i + 100;
foreach (int j in n) {
int i = j - 100; // คำนวณ Index กลับ
Console.WriteLine("Element[{0}] = {1}", i, j);
}
// String (IEnumerable)
foreach (char c in "Hello") Console.WriteLine(c);
// Dictionary
var dict = new Dictionary { { "A", 1 }, { "B", 2 } };
foreach (var kvp in dict) {
Console.WriteLine($"{kvp.Key} = {kvp.Value}");
}
ผลลัพธ์ (จากตัวอย่าง foreach)
Element[0] = 100
Element[1] = 101
Element[2] = 102
Element[3] = 103
Element[4] = 104
Element[5] = 105
Element[6] = 106
Element[7] = 107
Element[8] = 108
Element[9] = 109
Loop Control Statements
| Statement |
คำอธิบาย |
break |
ออกจาก Loop ทันที (Innermost Loop) |
continue |
ข้ามรอบนี้ ไปรอบถัดไปทันที |
goto |
กระโดดไป Label (หลีกเลี่ยงให้มากที่สุด) |
return |
ออกจาก Method ทั้งหมด |
ตัวอย่าง break/continue
for (int i = 0; i < 10; i++) {
if (i == 3) continue; // ข้าม 3
if (i == 7) break; // หยุดที่ 7
Console.Write(i + " "); // 0 1 2 4 5 6
}
เปรียบเทียบ Loop Types
| ด้าน |
for |
while |
do-while |
foreach |
| Condition Check |
Pre-test |
Pre-test |
Post-test |
Pre-test (Internal) |
| Min Iterations |
0 |
0 |
1 |
0 |
| Index Access |
✅ Yes |
Manual |
Manual |
❌ No (Direct) |
| Modify Collection |
✅ Safe (ถ้าถูกต้อง) |
✅ Safe |
✅ Safe |
❌ InvalidOperationException |
| Performance |
Fastest (Array) |
Fast |
Fast |
Slight Overhead (Enumerator) |
| Best For |
Known Count, Index Needed |
Unknown Count, Condition-based |
At Least Once, Menu/Input |
Read-only Iteration, LINQ |
Pattern Matching Switch (C# 8+) - Alternative to Loops
// แทน Loop บางกรณี
var result = items switch {
[] => "Empty",
[var first] => $"Single: {first}",
[var first, var second, ..var rest] => $"First: {first}, Second: {second}, Rest: {rest.Count}",
_ => "Multiple"
};