yield個人理解及簡明樣本

來源:互聯網
上載者:User

標籤:class   blog   http   tar   ext   com   

1.寫法有2種:
yield return <expression>和yield break
yield用於在迭代中返回一個值,並將值帶入下一次迭代中。yield break則意味著停止迭代。純粹的文字描述,一千個人有一千個說法,還是用代碼更容易說清楚。
2.官方樣本(略帶修改):

 private void button1_Click(object sender, EventArgs e)        {            string s = string.Empty;            foreach (int i in List.Power(2,8))            {                s += i.ToString() + ",";            }            MessageBox.Show(s);        }    public class List    {        //using System.Collections;        public static IEnumerable Power(int number, int exponent)        {            int counter = 0;            int result = 1;                        while (counter++ < exponent)            {                result = result * number;                yield return result;            }        }    }

運行樣本,發現power方法中的while代碼部分,每迴圈執行一次,即輸出一個值,並將這個值帶入下一次迴圈,而power函數並沒有每次被調用。

為了驗證,我們修改下官方範例程式碼,來看看我們的判斷是否有誤:

private void button1_Click(object sender, EventArgs e)        {            string s = string.Empty;            foreach (int i in List.Power())            {                s += i.ToString() + ",";            }            MessageBox.Show(s);        }    public static IEnumerable Power()        {            int counter = 0;            int result = 1;            int number = 2, exponent = 8;            while (counter++ < exponent)            {                result = result * number;                yield return result;            }        }

 運行結果與官方樣本相同,說明.net framework每次只把yield部分所在的部分代碼進行了迭代返回處理。

3.官方的另一個樣本為用yield作為屬性(輸出方式略有修改)。

 private void button2_Click(object sender, EventArgs e)        {            var theGalaxies = new Galaxies();            string ps = string.Empty;            foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy)            {                ps += (theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString() + " >> ");            }            MessageBox.Show(ps);        } 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 };            }        }

 輸出結果:

從這個例子可以看出yield其實就是臨時中斷執行,輸出後繼續執行而已。

可以修改下這個例子,看效果如何:

 public class Galaxies    {        List<Galaxy> ls = new List<Galaxy>();        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 System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy1        {            get            {                ls.Add(new Galaxy { Name = "Tadpole", MegaLightYears = 400 });                ls.Add(new Galaxy { Name = "Pinwheel", MegaLightYears = 25 });                ls.Add(new Galaxy { Name = "Milky Way", MegaLightYears = 0 });                ls.Add(new Galaxy { Name = "Andromeda", MegaLightYears = 3 });                int i = -1;                while (i++ < ls.Count - 1)                {                    yield return ls[i];                }            }        }    }

 調用NextGalaxy1後,結果與官方樣本結果相同,還可以進一步修改NextGalaxy1,使其更容易別理解:

 public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy1        {            get            {                ls.Add(new Galaxy { Name = "Tadpole", MegaLightYears = 400 });                ls.Add(new Galaxy { Name = "Pinwheel", MegaLightYears = 25 });                ls.Add(new Galaxy { Name = "Milky Way", MegaLightYears = 0 });                ls.Add(new Galaxy { Name = "Andromeda", MegaLightYears = 3 });                int i = 0;                while (i < ls.Count)                {                    yield return ls[i];                    i++;                }            }        }

 這樣看來就很容易理解其含義了,更進一步說就是一邊給你輸出結果,一邊繼續給你執行代碼,一舉兩得!

如果想中斷執行,則直接用yield break即可。

代碼如下:

 public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy1        {            get            {                ls.Add(new Galaxy { Name = "Tadpole", MegaLightYears = 400 });                ls.Add(new Galaxy { Name = "Pinwheel", MegaLightYears = 25 });                ls.Add(new Galaxy { Name = "Milky Way", MegaLightYears = 0 });                ls.Add(new Galaxy { Name = "Andromeda", MegaLightYears = 3 });                int i = -1;                while (i++ < ls.Count - 1)                {                    yield return ls[i];                    if (ls[i].MegaLightYears == 0)                    {                        yield break;                    }                }            }        }

 輸出結果為:

附官方連結:http://msdn.microsoft.com/zh-cn/library/9k7k7cf0.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.