ฉันเคยเห็นรูปแบบนี้ใน MSDN: yield breakแต่ฉันไม่รู้ว่ามันทำอะไร มีใครรู้บ้าง
MyList.Add(...) yield return ...หากคุณต้องการแยกวงออกก่อนเวลาอันควรและคืนรายการสำรองเสมือนที่คุณใช้yield break;
                ฉันเคยเห็นรูปแบบนี้ใน MSDN: yield breakแต่ฉันไม่รู้ว่ามันทำอะไร มีใครรู้บ้าง
MyList.Add(...) yield return ...หากคุณต้องการแยกวงออกก่อนเวลาอันควรและคืนรายการสำรองเสมือนที่คุณใช้yield break;
                คำตอบ:
มันระบุว่าตัววนซ้ำสิ้นสุดลงแล้ว คุณสามารถคิดว่าyield breakเป็นreturnคำสั่งที่ไม่ส่งคืนค่า
ตัวอย่างเช่นหากคุณกำหนดฟังก์ชั่นเป็นตัววนซ้ำเนื้อความของฟังก์ชันอาจมีลักษณะดังนี้:
for (int i = 0; i < 5; i++)
{
    yield return i;
}
Console.Out.WriteLine("You will see me");โปรดทราบว่าหลังจากวนรอบเสร็จสิ้นรอบทั้งหมดบรรทัดสุดท้ายจะถูกเรียกใช้งานและคุณจะเห็นข้อความในแอปคอนโซลของคุณ
หรือเช่นนี้กับyield break:
int i = 0;
while (true)
{
    if (i < 5)
    {
        yield return i;
    }
    else
    {
        // note that i++ will not be executed after this
        yield break;
    }
    i++;
}
Console.Out.WriteLine("Won't see me");ในกรณีนี้คำสั่งสุดท้ายจะไม่ดำเนินการเพราะเราออกจากฟังก์ชั่นก่อน
breakแทนyield breakในตัวอย่างของคุณไป? คอมไพเลอร์ไม่ได้บ่นเรื่องนั้น
                    breakในกรณีนี้จะหยุดวง แต่มันจะไม่ยกเลิกการดำเนินการวิธีการดังนั้นบรรทัดสุดท้ายจะถูกดำเนินการและ "จะไม่เห็นฉันข้อความ" จะเห็นจริง
                    NullReferenceExceptionรับตัวแจงนับของ IEnumerable ได้ในขณะที่การหยุดรับผลตอบแทนนั้นคุณไม่มี (มีอินสแตนซ์ที่ไม่มีองค์ประกอบ)
                    yield return xคอมไพเลอร์เตือนคุณต้องการให้เมธอดนี้เป็นน้ำตาล syntactic เพื่อสร้างEnumeratorวัตถุ แจงนับนี้มีวิธีการและทรัพย์สินMoveNext() CurrentMoveNext () ดำเนินการวิธีการจนกว่าจะมีคำสั่งและเปลี่ยนค่าที่เป็นyield return Currentครั้งต่อไปที่เรียกว่า MoveNext การดำเนินการจะดำเนินต่อจากที่นั่น yield breakตั้งค่าปัจจุบันเป็นโมฆะส่งสัญญาณการสิ้นสุดของตัวแจงนับเพื่อที่foreach (var x in myEnum())จะสิ้นสุด
                    สิ้นสุดบล็อกตัววนซ้ำ (เช่นบอกว่าไม่มีองค์ประกอบอีกต่อไปใน IEnumerable)
yieldคำหลักคุณสามารถทำซ้ำคอลเลกชันได้ทั้งสองทิศทางยิ่งไปกว่านั้นคุณสามารถใช้องค์ประกอบทุกอย่างของคอลเลคชั่นต่อไปไม่ได้อยู่ในแถวเดียวกันได้
                    yieldทำมัน ฉันไม่ได้บอกว่าคุณผิดฉันเห็นสิ่งที่คุณแนะนำ แต่ในเชิงวิชาการไม่มีตัววนซ้ำใน. NET มีเพียงตัวแจงนับ (ทิศทางเดียวไปข้างหน้า) - ซึ่งแตกต่างจาก stdc ++ ไม่มี "กรอบตัววนซ้ำทั่วไป" ที่กำหนดไว้ใน CTS / CLR LINQ ช่วยปิดช่องว่างด้วยวิธีการส่วนขยายที่ใช้yield return และวิธีการโทรกลับแต่เป็นวิธีส่วนขยายชั้นหนึ่งไม่ใช่ตัววนซ้ำชั้นหนึ่ง ผลลัพธ์IEnumerableไม่สามารถวนซ้ำไปในทิศทางอื่นนอกจากการส่งต่อผู้โทร
                    บอกตัววนซ้ำว่าถึงจุดสิ้นสุด
ตัวอย่างเช่น:
public interface INode
{
    IEnumerable<Node> GetChildren();
}
public class NodeWithTenChildren : INode
{
    private Node[] m_children = new Node[10];
    public IEnumerable<Node> GetChildren()
    {
        for( int n = 0; n < 10; ++n )
        {
            yield return m_children[ n ];
        }
    }
}
public class NodeWithNoChildren : INode
{
    public IEnumerable<Node> GetChildren()
    {
        yield break;
    }
}yieldโดยทั่วไปจะทำให้IEnumerable<T>วิธีการทำงานในลักษณะคล้ายกันกับด้าย (กำหนดไว้ล่วงหน้า)
yield returnเป็นเหมือนเธรดที่เรียกใช้ฟังก์ชัน "schedule" หรือ "sleep" เพื่อยกเลิกการควบคุม CPU เช่นเดียวกับเธรดIEnumerable<T>เมธอดจะควบคุมอีกครั้งที่จุดทันทีหลังจากนั้นตัวแปรโลคัลทั้งหมดที่มีค่าเดียวกับที่เคยมีก่อนที่จะถูกควบคุม
yield break เป็นเหมือนเธรดที่ถึงจุดสิ้นสุดของฟังก์ชันและสิ้นสุด
ผู้คนพูดถึง "เครื่องรัฐ" แต่เครื่องรัฐเป็น "เกลียว" ทั้งหมดจริงๆ เธรดมีสถานะบางอย่าง (ค่า Ie ของตัวแปรโลคัล) และแต่ละครั้งที่มีการกำหนดเวลาไว้จะต้องดำเนินการบางอย่างเพื่อให้ได้สถานะใหม่ จุดสำคัญเกี่ยวกับการyieldที่ไม่เหมือนกับเธรดระบบปฏิบัติการที่เราคุ้นเคยรหัสที่ใช้จะถูกตรึงในเวลาจนกว่าการวนซ้ำนั้นจะเป็นขั้นสูงหรือสิ้นสุดด้วยตนเอง
เรื่องทั้งหมดของบล็อก iterator ถูกปกคลุมอย่างดีในเรื่องนี้บทตัวอย่างฟรีจากจอน Skeet หนังสือC # ในความลึก
yield breakคำสั่งที่ทำให้เกิดการแจงนับหยุด มีผลบังคับใช้yield breakทำการแจงนับโดยไม่ต้องส่งคืนรายการเพิ่มเติมใด ๆ
พิจารณาว่าจริงๆแล้วมีสองวิธีที่วิธีการวนซ้ำสามารถหยุดการวนซ้ำได้ ในกรณีหนึ่งตรรกะของวิธีการสามารถออกจากวิธีการตามธรรมชาติหลังจากกลับรายการทั้งหมด นี่คือตัวอย่าง:
IEnumerable<uint> FindPrimes(uint startAt, uint maxCount)
{
    for (var i = 0UL; i < maxCount; i++)
    {
        startAt = NextPrime(startAt);
        yield return startAt;
    }
    Debug.WriteLine("All the primes were found.");
}ในตัวอย่างข้างต้นวิธี iterator จะหยุดดำเนินการตามธรรมชาติเมื่อmaxCountพบช่วงเวลา
yield breakคำสั่งเป็นวิธีการที่ iterator เพื่อยุติแจงอีก มันเป็นวิธีที่จะแยกออกจากการแจงนับก่อน นี่เป็นวิธีเดียวกันกับข้างบน เวลานี้เมธอดมีข้อ จำกัด เกี่ยวกับระยะเวลาที่เมธอดสามารถดำเนินการได้
IEnumerable<uint> FindPrimes(uint startAt, uint maxCount, int maxMinutes)
{
    var sw = System.Diagnostics.Stopwatch.StartNew();
    for (var i = 0UL; i < maxCount; i++)
    {
        startAt = NextPrime(startAt);
        yield return startAt;
        if (sw.Elapsed.TotalMinutes > maxMinutes)
            yield break;
    }
    Debug.WriteLine("All the primes were found.");
}yield breakขอให้สังเกตการเรียกร้องให้ ผลก็คือออกจากการแจงนับก่อน
แจ้งให้ทราบล่วงหน้าเกินไปว่าทำงานแตกต่างกันมากกว่าเพียงแค่ธรรมดาyield break breakในตัวอย่างข้างต้นออกมาจากวิธีการโดยไม่ทำให้การเรียกร้องให้yield breakDebug.WriteLine(..)
ที่นี่http://www.alteridem.net/2007/08/22/the-yield-statement-in-c/เป็นตัวอย่างที่ดีมาก:
สาธารณะแบบคงที่ IEnumerable <int> ช่วง (int min, int max)
{
   ในขณะที่ (จริง)
   {
      if (min> = max)
      {
         ทำลายผลผลิต;
      }
      ผลตอบแทนคืนขั้นต่ำ ++;
   }
}
และคำอธิบายว่าถ้าyield breakคำสั่งถูกตีภายในเมธอดการดำเนินการของเมธอดนั้นจะหยุดโดยไม่มีการส่งคืน มีบางเวลาที่สถานการณ์เมื่อคุณไม่ต้องการให้ผลลัพธ์ใด ๆ จากนั้นคุณสามารถใช้ตัวแบ่งผลตอบแทน
การหยุดรับผลตอบแทนเป็นเพียงวิธีการบอกผลตอบแทนเป็นครั้งสุดท้ายและไม่คืนค่าใด ๆ
เช่น
// returns 1,2,3,4,5
IEnumerable<int> CountToFive()
{
    yield return 1;
    yield return 2;
    yield return 3;
    yield return 4;
    yield return 5;
    yield break;
    yield return 6;
    yield return 7;
    yield return 8;
    yield return 9;
 }หากสิ่งที่คุณหมายถึงโดย "สิ่งที่ทำให้ผลตอบแทนที่แท้จริงทำ" คือ "มันทำงานอย่างไร" - ดูบล็อกของ Raymond Chen สำหรับรายละเอียดhttps://devblogs.microsoft.com/oldnewthing/20080812-00/?p=21273
ตัววนซ้ำ C # สร้างโค้ดที่ซับซ้อนมาก
คีย์เวิร์ด yield ใช้พร้อมกับคีย์เวิร์ด return เพื่อจัดเตรียมค่าให้กับอ็อบเจ็กต์ตัวแจงนับ ผลตอบแทนผลตอบแทนระบุค่าหรือค่าผลตอบแทน เมื่อถึงคำสั่งคืนผลตอบแทนที่ตั้งปัจจุบันจะถูกเก็บไว้ การดำเนินการจะเริ่มต้นใหม่จากตำแหน่งนี้ในครั้งต่อไปที่มีการเรียกตัววนซ้ำ
ในการอธิบายความหมายโดยใช้ตัวอย่าง:
public IEnumerable<int> SampleNumbers() { int counter = 0; yield return counter; counter = counter + 2; yield return counter; counter = counter + 3; yield return counter ; }
ค่าที่ส่งคืนเมื่อมีการทำซ้ำคือ: 0, 2, 5
สิ่งสำคัญคือให้สังเกตว่าตัวแปรตัวนับในตัวอย่างนี้เป็นตัวแปรท้องถิ่น หลังจากการวนซ้ำครั้งที่สองซึ่งส่งคืนค่า 2 การวนซ้ำครั้งที่สามเริ่มต้นจากที่เหลือก่อนหน้าขณะที่รักษาค่าก่อนหน้าของตัวแปรโลคอลที่ชื่อว่าตัวนับซึ่งเป็น 2
yield breakไม่
                    yield returnจริง ๆ แล้วสนับสนุนการคืนค่าหลายค่า บางทีนั่นอาจไม่ใช่สิ่งที่คุณตั้งใจจริงๆ แต่นั่นเป็นวิธีที่ฉันอ่าน
                    yield breakมันไม่มีตัวแจงนับระดับภาษาเช่นforeach- เมื่อใช้ตัวแจงนับyield breakจะให้ค่าจริง ตัวอย่างนี้ดูเหมือนว่าลูปที่ไม่ได้ควบคุม คุณแทบจะไม่เคยเห็นรหัสนี้ในโลกแห่งความเป็นจริง (เราทุกคนสามารถนึกถึงกรณีขอบบางอย่างแน่นอน) และยังไม่มี "ตัววนซ้ำ" ที่นี่ "iterator block" ไม่สามารถขยายเกินกว่าวิธีการเป็นข้อกำหนดของภาษา สิ่งที่ส่งคืนจริง ๆ คือ "นับได้" ดูเพิ่มเติมได้ที่: stackoverflow.com/questions/742497//