Iterator Method คือเมธอดที่ทำการวนซ้ำ (iterate) ผ่านคอลเลกชันแบบกำหนดเอง โดยใช้คำสั่ง yield return เพื่อคืนค่าแต่ละรายการทีละรายการ Iterator จะจำตำแหน่งปัจจุบันไว้ และในรอบถัดไปจะคืนค่ารายการถัดไป
หลักการทำงานของ yield return
- เมื่อเจอ
yield returnโปรแกรมจะหยุดชั่วคราว คืนค่ากลับไปให้ผู้เรียก - สถานะการทำงานถูกเก็บไว้ (state machine)
- เมื่อขอค่าถัดไป (MoveNext) จะทำงานต่อจากจุดที่หยุด
- จบการทำงานเมื่อถึง
yield breakหรือจบเมธอด
ตัวอย่างพื้นฐาน
using System;
using System.Collections.Generic;
namespace Demo {
class Program {
// Iterator method - คืนค่า IEnumerable
public static IEnumerable Display() {
int[] arr = new int[] { 99, 45, 76 };
foreach (var val in arr) {
yield return val.ToString(); // คืนค่าทีละตัว
}
}
public static void Main(string[] args) {
IEnumerable elements = Display();
foreach (var element in elements) {
Console.WriteLine(element);
}
}
}
}
ผลลัพธ์
99
45
76
การใช้งาน yield break
public static IEnumerable GetNumbers(int max) {
for (int i = 0; i < max; i++) {
if (i == 5) yield break; // หยุดการวนซ้ำทันที
yield return i;
}
}
// ผลลัพธ์: 0, 1, 2, 3, 4
ประโยชน์ของ Iterator (Lazy Evaluation)
- Memory Efficient - ไม่ต้องสร้างคอลเลกชันทั้งหมดในหน่วยความจำ
- Deferred Execution - คำนวณค่าเฉพาะเมื่อถูกขอ (on-demand)
- Infinite Sequences - สร้างลำดับอนันต์ได้ (เช่น Fibonacci)
- Pipeline Friendly - ใช้กับ LINQ ได้อย่างมีประสิทธิภาพ
ตัวอย่าง: Fibonacci แบบ Iterator
public static IEnumerable Fibonacci() {
long a = 0, b = 1;
while (true) {
yield return a;
long temp = a + b;
a = b;
b = temp;
}
}
// ใช้งาน - เอาแค่ 10 ตัวแรก
var first10 = Fibonacci().Take(10);
foreach (var n in first10) Console.WriteLine(n);
IEnumerable vs IEnumerator
| Interface | หน้าที่ |
|---|---|
IEnumerable<T> |
มีเมธอด GetEnumerator() คืนค่า Enumerator |
IEnumerator<T> |
มี Current, MoveNext(), Reset() |
Compiler จะสร้าง State Machine class ที่ implement ทั้งสอง interface ให้อัตโนมัติเมื่อใช้ yield