麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

C# 基礎小知識之yield 關鍵字

2019-11-17 02:28:16
字體:
來源:轉載
供稿:網友
C# 基礎小知識之yield 關鍵字

對于yield關鍵字我們首先看一下msdn的解釋:

如果你在語句中使用yield關鍵字,則意味著它在其中出現的方法、運算符或get訪問器是迭代器。通過使用yield定義迭代器,可在實現自定義集合類型的IEnumerable和IEnumerator模式時無需其他顯式類(保留枚舉狀態的類,有關示例,請參閱IEnumerator<T>)。

yield是一個語法糖

看msdn 的解釋總是讓人感覺生硬難懂。其實yield關鍵字很好理解。首先我們對于性質有個了解。yield是一個語法糖。既然yield是在C#中的一個語法糖,那么就說明yield是對一種復雜行為的簡化,就是將一段代碼簡化為一種簡單的形式,方便我們程序員使用。

那么yield到底是對什么行為的簡化。我們首先來看一下yield的使用場景。

還是來看msdn上的例子。

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Consoleapplication2{    class PRogram    {        static void Main(string[] args)        {                     foreach (int i in Power(2, 8, ""))            {                Console.Write("{0} ", i);            }            Console.ReadKey();        }        public static IEnumerable<int> Power(int number, int exponent, string s)        {            int result = 1;            for (int i = 0; i < exponent; i++)            {                result = result * number;                yield return result;            }            yield return 3;            yield return 4;            yield return 5;        }    }}

這是msdn上yield的一種使用場景。

我們首先看一下下面的Power方法。該靜態方法返回一個IEnumerablel<int>類型的參數。按照我們平常的做法。應該對數據執行一定操作,然后return一個IEnumerablel<int>類型的參數。我們把Power方法改造如下:

 public static IEnumerable<int> Power(int number, int exponent, string s)        {            int result = 1;            //接口不能實例化,我們這兒new一個實現了IEnumerable接口的List            IEnumerable<int> example = new List<int>();            for (int i = 0; i < exponent; i++)            {                result = result * number;                (example as List<int>).Add(result);            }            return example;        }

這是我們平常的思路。但是這樣做就有個問題。這兒要new一個List,或者任何實現了IEnumerable接口的類型。這樣也太麻煩了吧。要知道IEnumerable是一個常用的返回類型。每次使用都要new一個LIst,或者其他實現了該接口的類型。與其使用其他類型,不如我們自己定制一個實現了IEnumerable接口專門用來返回IEnumerable類型的類型。我們自己定制也很麻煩。所以微軟幫我們定制好了。這個類是什么,那就是yield關鍵字這個語法糖。

語法糖的實現(實現IEnumerable<T>接口的類)

我們來看一下yield的反編譯代碼。

namespace ConsoleApplication2{    using System;    using System.Collections;    using System.Collections.Generic;    using System.Diagnostics;    using System.Runtime.CompilerServices;    internal class Program    {        private static void Main(string[] args)        {            IEnumerable<int> enumerable = Power(2, 8);            Console.WriteLine("Begin to iterate the collection.");            foreach (int num in Power(2, 8))            {                Console.Write("{0} ", num);            }            Console.ReadKey();        }        public static IEnumerable<int> Power(int number, int exponent)        {            <Power>d__0 d__ = new <Power>d__0(-2);            d__.<>3__number = number;            d__.<>3__exponent = exponent;            return d__;        }        [CompilerGenerated]        private sealed class <Power>d__0 : IEnumerable<int>, IEnumerable, IEnumerator<int>, IEnumerator, IDisposable        {            private int <>1__state;            private int <>2__current;            public int <>3__exponent;            public int <>3__number;            private int <>l__initialThreadId;            public int <result>5__1;            public int exponent;            public int number;            [DebuggerHidden]            public <Power>d__0(int <>1__state)            {                this.<>1__state = <>1__state;                this.<>l__initialThreadId = Environment.CurrentManagedThreadId;            }            private bool MoveNext()            {                switch (this.<>1__state)                {                    case 0:                        this.<>1__state = -1;                        this.<result>5__1 = 1;                        Console.WriteLine("Begin to invoke GetItems() method");                        this.<>2__current = 3;                        this.<>1__state = 1;                        return true;                    case 1:                        this.<>1__state = -1;                        this.<>2__current = 4;                        this.<>1__state = 2;                        return true;                    case 2:                        this.<>1__state = -1;                        this.<>2__current = 5;                        this.<>1__state = 3;                        return true;                    case 3:                        this.<>1__state = -1;                        break;                }                return false;            }            [DebuggerHidden]            IEnumerator<int> IEnumerable<int>.GetEnumerator()            {                Program.<Power>d__0 d__;                if ((Environment.CurrentManagedThreadId == this.<>l__initialThreadId) && (this.<>1__state == -2))                {                    this.<>1__state = 0;                    d__ = this;                }                else                {                    d__ = new Program.<Power>d__0(0);                }                d__.number = this.<>3__number;                d__.exponent = this.<>3__exponent;                return d__;            }            [DebuggerHidden]            IEnumerator IEnumerable.GetEnumerator()            {                return this.System.Collections.Generic.IEnumerable<System.Int32>.GetEnumerator();            }            [DebuggerHidden]            void IEnumerator.Reset()            {                throw new NotSupportedException();            }            void IDisposable.Dispose()            {            }            int IEnumerator<int>.Current            {                [DebuggerHidden]                get                {                    return this.<>2__current;                }            }            object IEnumerator.Current            {                [DebuggerHidden]                get                {                    return this.<>2__current;                }            }        }    }}
View Code

反編譯代碼有三部分,其中程序的入口點 private static void Main(string[] args) Power方法 public static IEnumerable<int> Power(int number, int exponent) 和我們自己寫的代碼一樣,但是反編譯代碼中還多了一個密封類

private sealed class <Power>d__0 : IEnumerable<int>, IEnumerable, IEnumerator<int>, IEnumerator, IDisposable

現在情況已經明了了。yield這個語法糖實現了一個實現IEnumerable<int>接口的類來返回我們需要到IEnumerable<int>類型的數據。

我們再看一下反編譯后的Power方法

 public static IEnumerable<int> Power(int number, int exponent)        {            <Power>d__0 d__ = new <Power>d__0(-2);            d__.<>3__number = number;            d__.<>3__exponent = exponent;            return d__;        }

此時就確認,的確是使用了實現枚舉接口的類來返回我們需要的數據類型。

每次yield return <expression>;就會像該類的實例中添加 一條數據。當yield break;的時候停止添加。

至此yield的用法就很清楚了。當我們需要返回IEnumerable類型的時候,直接yield返回數據就可以了。也不用new一個list,或其他類型。所以yield是一個典型的語法糖。

yield使用中的特殊情況

我們看到編譯器將我們yield的數據添加到了一個集合中。Power方法在編譯器中實例化了一個實現枚舉接口的類型。但是我們在Power方法中寫一些方法,編譯器會如何處理

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApplication2{    class Program    {        static void Main(string[] args)        {            //這兒調用了方法。            var test = Power(2, 8, "");            Console.WriteLine("Begin to iterate the collection.");            //Display powers of 2 up to the exponent of 8:            foreach (int i in Power(2, 8, ""))            {                Console.Write("{0} ", i);
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 欧美成人午夜 | 久久久精品网 | 人与xxxxhdxxxhdxx| 国产做爰全免费的视频黑人 | 人与xxxxhdxxxhdxx| 中文字幕一区二区三区久久 | 午夜精品在线视频 | 欧美精品一区二区三区久久久 | 最新av网址在线观看 | 久久精品日产高清版的功能介绍 | 欧美不卡视频在线观看 | 欧美成人精品一区二区 | 国产精品热 | 国产成人高潮免费观看精品 | 男女羞羞在线观看 | 日本精品免费观看 | 国产精品久久久久久久久久大牛 | pornoⅹxxxxhd麻豆 | 成人在线观看免费视频 | 欧洲成人精品 | 久产久精品 | 羞羞视频免费网站 | av噜噜噜噜 | 福利免费在线观看 | www国产成人免费观看视频,深夜成人网 | 久久精品一区二区三 | 最近国产中文字幕 | 粉嫩粉嫩一区二区三区在线播放 | 粉嫩蜜桃麻豆免费大片 | 欧美77| 成人精品免费在线观看 | 成人午夜激情网 | 国产亚洲精彩视频 | 99精品在线视频观看 | 天堂亚洲一区 | 成人毛片视频免费看 | 在线看免费观看av | 黄色一级片免费观看 | 老女人碰碰在线碰碰视频 | 欧美大胆xxxx肉体摄影 | 欧美成人免费tv在线播放 |