0Pricing
C# Academy · บทเรียน

เมธอดตัววนซ้ำด้วย yield return

สร้างลำดับข้อมูลทีละองค์ประกอบ

เมธอดตัววนซ้ำด้วย yield return เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

เมธอดตัววนซ้ำคืออะไร

เมธอดตัววนซ้ำจะสร้างลำดับของค่าทีละค่าโดยใช้ yield return คอมไพเลอร์จะแปลงเมธอดนี้เป็นเครื่องจักรสถานะ คุณจึงไม่ต้องสร้างและจัดการรายการด้วยตนเอง

การใช้คำสั่งส่งคืนค่าแบบทยอยสร้างครั้งแรกของคุณ

แต่ละ yield return จะส่งค่าหนึ่งค่ากลับไปยังผู้เรียก แล้วหยุดเมธอดไว้ชั่วคราว การทำงานจะดำเนินต่อจากคำสั่งดังกล่าวเมื่อเริ่มการวนซ้ำครั้งถัดไป

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> FirstThree()
    {
        yield return 1;
        yield return 2;
        yield return 3;
    }

    public static void Main()
    {
        foreach (var n in FirstThree())
            Console.WriteLine(n);
    }
}

คำสั่งส่งคืนค่าแบบทยอยสร้างภายในลูป

ตัววนซ้ำส่วนใหญ่มักส่งค่าจากภายในลูป ในที่นี้เราสร้างจำนวนคู่ชุดแรกตาม count ค่าโดยไม่ต้องจัดสรรคอลเลกชันเลย

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> Evens(int count)
    {
        for (int i = 0; i < count; i++)
            yield return i * 2;
    }

    public static void Main()
    {
        foreach (var n in Evens(5))
            Console.WriteLine(n);
    }
}

เมธอดส่งคืน IEnumerable

เมธอดตัววนซ้ำต้องส่งคืน IEnumerable<T> หรือ IEnumerator<T> หรือชนิดที่ไม่ใช่ชนิดข้อมูลทั่วไปที่สอดคล้องกัน คุณจะไม่เขียน return พร้อมค่า แต่จะใช้เฉพาะ yield return เท่านั้น

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<string> Greetings()
    {
        yield return "hello";
        yield return "hi";
        yield return "hey";
    }

    public static void Main()
    {
        foreach (var g in Greetings())
            Console.WriteLine(g);
    }
}

การทำงานหยุดและดำเนินต่อได้

สถานะระหว่างการส่งคืนค่าแต่ละครั้งจะถูกเก็บรักษาโดยอัตโนมัติ ตัวแปรภายในเครื่องยังคงค่าของตนไว้ระหว่างการหยุดชั่วคราว จึงทำให้การสร้างผลรวมสะสมทำได้ง่าย

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> RunningTotal(IEnumerable<int> nums)
    {
        int total = 0;
        foreach (var n in nums)
        {
            total += n;
            yield return total;
        }
    }

    public static void Main()
    {
        foreach (var t in RunningTotal(new[] { 1, 2, 3, 4 }))
            Console.WriteLine(t);
    }
}

การสร้างลำดับไม่สิ้นสุด

เนื่องจากค่าต่าง ๆ ถูกสร้างขึ้นเมื่อมีการร้องขอ ตัววนซ้ำจึงสามารถอธิบายลำดับไม่สิ้นสุดได้อย่างปลอดภัย ผู้เรียกเป็นผู้ตัดสินใจว่าจะหยุดดึงค่าเมื่อใด

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> Naturals()
    {
        int i = 1;
        while (true) yield return i++;
    }

    public static void Main()
    {
        int taken = 0;
        foreach (var n in Naturals())
        {
            Console.WriteLine(n);
            if (++taken == 5) break;
        }
    }
}

การแปลงลำดับอินพุต

ตัววนซ้ำเหมาะอย่างยิ่งสำหรับการสร้างกระบวนการประมวลผลต่อเนื่อง โดยอ่านรายการจากลำดับหนึ่ง แปลงรายการเหล่านั้น แล้วส่งคืนผลลัพธ์เมื่อมีการร้องขอ

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<string> Labelled(IEnumerable<int> nums)
    {
        foreach (var n in nums)
            yield return "item-" + n;
    }

    public static void Main()
    {
        foreach (var s in Labelled(new[] { 10, 20, 30 }))
            Console.WriteLine(s);
    }
}

การกรองด้วยตัววนซ้ำ

หากต้องการกรอง เพียงส่งคืนเฉพาะรายการที่คุณต้องการ รายการที่ข้ามไปจะไม่ถูกสร้างขึ้นเลย ดังนั้นโค้ดถัดไปจึงไม่เคยมองเห็นรายการเหล่านั้น

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> OnlyPositive(IEnumerable<int> nums)
    {
        foreach (var n in nums)
            if (n > 0) yield return n;
    }

    public static void Main()
    {
        foreach (var n in OnlyPositive(new[] { -2, 5, -1, 8 }))
            Console.WriteLine(n);
    }
}

คอมไพเลอร์สร้างเครื่องจักรสถานะ

เบื้องหลัง คอมไพเลอร์จะเขียนตัววนซ้ำของคุณใหม่เป็นคลาสที่นำ IEnumerator<T> ไปใช้ โดยติดตามฟิลด์สถานะที่ซ่อนอยู่และค่า Current คุณจะได้รับกลไกทั้งหมดนี้โดยไม่ต้องเขียนเอง

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<char> Letters()
    {
        yield return 'a';
        yield return 'b';
        yield return 'c';
    }

    public static void Main()
    {
        IEnumerator<char> e = Letters().GetEnumerator();
        while (e.MoveNext())
            Console.WriteLine(e.Current);
    }
}

การประกอบตัววนซ้ำหลายตัว

ตัววนซ้ำเชื่อมต่อกันได้อย่างเป็นธรรมชาติ เพราะแต่ละตัวส่งคืน IEnumerable<T> คุณสามารถส่งเอาต์พุตจากตัววนซ้ำหนึ่งไปยังตัวถัดไป เพื่อสร้างกระบวนการประมวลผลต่อเนื่องที่อ่านเข้าใจง่าย

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<int> Range(int start, int count)
    {
        for (int i = 0; i < count; i++) yield return start + i;
    }
    static IEnumerable<int> Squares(IEnumerable<int> nums)
    {
        foreach (var n in nums) yield return n * n;
    }

    public static void Main()
    {
        foreach (var n in Squares(Range(1, 4)))
            Console.WriteLine(n);
    }
}

ลองทำด้วยตัวเอง

เขียนตัววนซ้ำที่แบ่งลำดับอินพุตออกเป็นชุดย่อยขนาดคงที่ ตัววนซ้ำจะส่งคืนรายการเมื่อมีการร้องขอ ซึ่งแสดงให้เห็นว่าคุณสามารถใส่ตรรกะได้มากเพียงใดในตัววนซ้ำที่สะอาดและกระชับเพียงตัวเดียว

using System;
using System.Collections.Generic;

public class Program
{
    static IEnumerable<List<int>> Batch(IEnumerable<int> source, int size)
    {
        var bucket = new List<int>();
        foreach (var n in source)
        {
            bucket.Add(n);
            if (bucket.Count == size) { yield return bucket; bucket = new List<int>(); }
        }
        if (bucket.Count > 0) yield return bucket;
    }

    public static void Main()
    {
        foreach (var group in Batch(new[] { 1, 2, 3, 4, 5 }, 2))
            Console.WriteLine(string.Join(",", group));
    }
}

ตรวจสอบอย่างรวดเร็ว

ทบทวนการทำงานของเมธอดตัววนซ้ำ

สรุปทบทวน

เมธอดตัววนซ้ำใช้ yield return เพื่อสร้างลำดับเมื่อมีการร้องขอ

  • เมธอดจะส่งคืน IEnumerable<T> หรือ IEnumerator<T>
  • แต่ละ yield return จะส่งค่าหนึ่งค่าและหยุดชั่วคราว โดยรักษาสถานะของตัวแปรภายในเครื่องไว้
  • เมธอดเหล่านี้สามารถอธิบายลำดับไม่สิ้นสุดได้อย่างปลอดภัย
  • คอมไพเลอร์จะสร้างเครื่องจักรสถานะให้คุณ

คำถามที่พบบ่อย

บทเรียน “เมธอดตัววนซ้ำด้วย yield return” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “เมธอดตัววนซ้ำด้วย yield return” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “เมธอดตัววนซ้ำด้วย yield return”

สร้างลำดับข้อมูลทีละองค์ประกอบ คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “เมธอดตัววนซ้ำด้วย yield return” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม

ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. เมธอดตัววนซ้ำด้วย yield return
  2. yield break และการสิ้นสุดก่อนกำหนด
  3. ความหมายของการประเมินค่าแบบขี้เกียจ
  4. ชนิด Enumerable แบบกำหนดเอง
← กลับไปที่ C# Academy