共用方式為


yield (C# 參考)

在陳述式中使用 yield 關鍵字時,您會表示關鍵字所在的方法、運算子或 get 存取子是迭代器。 如果使用 yield 定義迭代器,當您為自訂集合類型實作 IEnumerableIEnumerator 模式時,就不需要明確的額外類別 (保存列舉之狀態的類別,請參閱 IEnumerator 中的範例)。

下列範例將示範兩種形式的 yield 陳述式。

yield return <expression>;
yield break;

備註

您可以使用 yield return 陳述式一次傳回一個元素。

藉由使用 foreach 陳述式或 LINQ 查詢就可以使用 Iterator 方法。 foreach 迴圈的每個反覆項目都會呼叫 Iterator 方法。 當 Iterator 方法中到達 yield return 陳述式時,就會傳回 expression 並保留程式碼中目前的位置。 下一次呼叫 Iterator 函式時,便會從這個位置重新開始執行。

您可以使用 yield break 陳述式結束反覆項目。

如需有關迭代器的詳細資訊,請參閱 Iterator (C# 和 Visual Basic)

Iterator 方法和 get 存取子

迭代器的宣告必須符合下列需求:

傳回 IEnumerableIEnumerator 的 yield 類型迭代器為 object。如果迭代器傳回 IEnumerableIEnumerator,則 yield return 陳述式中必須進行從運算式類型轉換成泛型類型參數的隱含轉換。

具有下列特性的方法中不可包含 yield return 或 yield break 陳述式:

例外狀況處理

yield return 陳述式不能位於 try-catch 區塊內。 yield return 陳述式可以位於 try-finally 陳述式的 try 區塊內。

yield break 陳述式可以位於 try 區塊或 catch 區塊中,但是不可位於 finally 區塊中。

如果 foreach 主體 (在 Iterator 方法之外) 擲回例外狀況,則會執行 Iterator 方法中的 finally 區塊。

技術實作

下列程式碼會從 Iterator 方法傳回 IEnumerable<string>,然後逐一查看其元素。

IEnumerable<string> elements = MyIteratorMethod();
foreach (string element in elements)
{
   …
}

對 MyIteratorMethod 的呼叫不會執行方法的主體。 呼叫會改為將 IEnumerable<string> 傳回至 elements 變數中。

在 foreach 迴圈的反覆項目上,會針對 elements 呼叫 MoveNext 方法。 這個呼叫會執行 MyIteratorMethod 的主體,直到下一個 yield return 陳述式為止。 yield return 陳述式所傳回的運算式不僅會判斷迴圈主體所使用之 element 變數的值,也會判斷元素的 Current 屬性,該屬性會是 IEnumerable<string>

在 foreach 迴圈的每個後續反覆項目上,迭代器主體會從上次停止的位置繼續執行,並且在到達 yield return 陳述式時再次停止。 當 Iterator 方法結束或到達 yield break 陳述式時,foreach 迴圈便完成。

範例

下列範例中的陳述式 yield return 位於 for 迴圈內。 Process 中 foreach 陳述式主體的每個反覆項目都會建立對 Power Iterator 函式的呼叫。 每次呼叫 Iterator 函式都會執行下一個 yield return 陳述式,這會在 for 迴圈的下一個反覆項目期間發生。

Iterator 方法的傳回類型是 IEnumerable,其為 Iterator 介面類型。 呼叫 Iterator 方法時,它會傳回包含數字乘冪的可列舉物件。

public class PowersOf2
{
    static void Main()
    {
        // Display powers of 2 up to the exponent of 8: 
        foreach (int i in Power(2, 8))
        {
            Console.Write("{0} ", i);
        }
    }

    public static System.Collections.Generic.IEnumerable<int> Power(int number, int exponent)
    {
        int result = 1;

        for (int i = 0; i < exponent; i++)
        {
            result = result * number;
            yield return result;
        }
    }

    // Output: 2 4 8 16 32 64 128 256
}

下列範例將示範本身為迭代器的 get 存取子。 在這個範例中,每個 yield return 陳述式都會傳回使用者定義類別的執行個體。

public static class GalaxyClass
{
    public static void ShowGalaxies()
    {
        var theGalaxies = new Galaxies();
        foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy)
        {
            Debug.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString());
        }
    }

    public class Galaxies
    {

        public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy
        {
            get
            {
                yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 };
                yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 };
                yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 };
                yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 };
            }
        }

    }

    public class Galaxy
    {
        public String Name { get; set; }
        public int MegaLightYears { get; set; }
    }
}

C# 語言規格

如需詳細資訊,請參閱<C# 語言規格>。語言規格是 C# 語法及用法的限定來源。

請參閱

參考

foreach、in (C# 參考)

概念

C# 程式設計手冊

其他資源

C# 參考

Iterator (C# 和 Visual Basic)