• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Onway

            我是一只菜菜菜菜鳥...
            posts - 61, comments - 56, trackbacks - 0, articles - 34

            可枚舉對(duì)象與枚舉器

            Posted on 2015-08-01 14:00 Onway 閱讀(600) 評(píng)論(1)  編輯 收藏 引用 所屬分類: 使用說明
            1,最先學(xué)會(huì)的是,繼承了IEnumerable接口的類都可以使用foreach遍歷,但一直沒有多想。

            2,IEnumerable和IEnumerable<out T>的定義:
                public interface IEnumerable
                {
                    IEnumerator GetEnumerator();
                }

                public interface IEnumerable<out T> : IEnumerable
                {
                    IEnumerator<T> GetEnumerator();
                }

            3,IEnumerator和IEnumerator<out T>的定義:
                public interface IEnumerator
                {
                    object Current { get; }
                    bool MoveNext();
                    void Reset();
                }

                public interface IEnumerator<out T> : IDisposable, IEnumerator
                {
                    T Current { get; }
                }

            4,可以這么理解兩個(gè)接口:可枚舉對(duì)象返回一個(gè)枚舉器用于枚舉其內(nèi)部狀態(tài)。

            5,每一次foreach之后,都會(huì)重新調(diào)用GetEnumerator,foreach語(yǔ)句并不會(huì)調(diào)用Enumerator的Reset方法;
            對(duì)于泛型版本的GetEnumerator<T>,foreach同樣不會(huì)調(diào)用Reset方法,但會(huì)調(diào)用Dispose。
            以下是測(cè)試代碼的輸出:
            [08.177] StringEnumerator
            [08.191] StringMoveNext
            [08.191] StringCurrent
            Hello
            [08.191] StringMoveNext
            [08.191] StringCurrent
            World
            [08.191] StringMoveNext
            [08.191] StringCurrent
            !
            [08.192] StringMoveNext
            [08.192] StringEnumerator
            [08.192] StringMoveNext
            [08.192] StringCurrent
            Hello
            [08.192] StringMoveNext
            [08.192] StringCurrent
            World
            [08.193] StringMoveNext
            [08.193] StringCurrent
            !
            [08.193] StringMoveNext
            [08.195] NumberEnumerator
            [08.196] NumberMoveNext
            [08.196] NumberCurrent<T>
            1
            [08.198] NumberMoveNext
            [08.199] NumberCurrent<T>
            2
            [08.199] NumberMoveNext
            [08.201] NumberDispose
            [08.201] NumberEnumerator
            [08.201] NumberMoveNext
            [08.202] NumberCurrent<T>
            1
            [08.202] NumberMoveNext
            [08.203] NumberCurrent<T>
            2
            [08.203] NumberMoveNext
            [08.203] NumberDispose

            using System;
            using System.Collections;
            using System.Collections.Generic;

            namespace ConsoleTest
            {
                public class Program
                {
                    static void Main(string[] args)
                    {
                        StringEnumerable se = new StringEnumerable(); 
                        foreach (string s in se)
                        {
                            Console.WriteLine(s);
                        }
                        foreach (string s in se)
                        {
                            Console.WriteLine(s);
                        }
                        Console.WriteLine();

                        NumberEnumerable<double> ne = new NumberEnumerable<double>(new double[] { 1.0, 2.0 });
                        foreach (double d in ne)
                        {
                            Console.WriteLine(d);
                        }
                        foreach (double d in ne)
                        {
                            Console.WriteLine(d);
                        }
                        Console.ReadKey();
                    }
                }

                class StringEnumerable : IEnumerable
                {
                    private string[] strs = new string[] { "Hello", "World", "!" };

                    public IEnumerator GetEnumerator()
                    {
                        return new StringEnumerator(strs);
                    }
                }

                class StringEnumerator : IEnumerator
                {
                    private string[] strs;
                    private int index;
                    private object current;

                    public StringEnumerator(string[] strs)
                    {
                        Console.WriteLine("[{0}] StringEnumerator", DateTime.Now.ToString("ss.fff"));
                        this.strs = strs;
                        index = -1;
                    }

                    public object Current
                    {
                        get
                        {
                            Console.WriteLine("[{0}] StringCurrent", DateTime.Now.ToString("ss.fff"));
                            return current;
                        }
                    }

                    public bool MoveNext()
                    {
                        Console.WriteLine("[{0}] StringMoveNext", DateTime.Now.ToString("ss.fff"));
                        while (++index < strs.Length)
                        {
                            current = strs[index];
                            return true;
                        }
                        return false;
                    }

                    public void Reset()
                    {
                        Console.WriteLine("[{0}] StringReset", DateTime.Now.ToString("ss.fff"));
                        index = -1;
                    }
                }

                class NumberEnumerable<T> : IEnumerable<T>
                {
                    private T[] ts;

                    public NumberEnumerable(T[] ts)
                    {
                        this.ts = ts;
                    }

                    IEnumerator IEnumerable.GetEnumerator()
                    {
                        return new NumberEnumerator<T>(ts);
                    }

                    IEnumerator<T> IEnumerable<T>.GetEnumerator()
                    {
                        return new NumberEnumerator<T>(ts);
                    }
                }

                class NumberEnumerator<T> : IEnumerator<T>
                {
                    private T[] strs;
                    private int index;
                    private T current;

                    public NumberEnumerator(T[] strs)
                    {
                        Console.WriteLine("[{0}] NumberEnumerator", DateTime.Now.ToString("ss.fff"));
                        this.strs = strs;
                        index = -1;
                    }

                    object IEnumerator.Current
                    {
                        get
                        {
                            Console.WriteLine("[{0}] NumberCurrent", DateTime.Now.ToString("ss.fff"));
                            return current;
                        }
                    }

                    T IEnumerator<T>.Current
                    {
                        get
                        {
                            Console.WriteLine("[{0}] NumberCurrent<T>", DateTime.Now.ToString("ss.fff"));
                            return current;
                        }
                    }

                    public bool MoveNext()
                    {
                        Console.WriteLine("[{0}] NumberMoveNext", DateTime.Now.ToString("ss.fff"));
                        while (++index < strs.Length)
                        {
                            current = strs[index];
                            return true;
                        }
                        return false;
                    }

                    public void Reset()
                    {
                        Console.WriteLine("[{0}] NumberReset", DateTime.Now.ToString("ss.fff"));
                        index = -1;
                    }

                    public void Dispose()
                    {
                        Console.WriteLine("[{0}] NumberDispose", DateTime.Now.ToString("ss.fff"));
                        index = -1;
                    }
                }
            }

            6
            ,foreach默認(rèn)可枚舉對(duì)象的GetEnumerator方法,其他需要進(jìn)行枚舉的方法需要返回IEnumerable或者IEnumerable<T>,以供foreach調(diào)用其GetEnumerator方法。

            7,yield語(yǔ)句只能使用在返回IEnumerable或者IEnumerator接口的方法中。
            yield語(yǔ)句會(huì)被編譯為實(shí)現(xiàn)了IEnumerator<T>的內(nèi)部枚舉器。
            以下是代碼使用.NET Reflector 7.0反編譯出來(lái)的結(jié)果:
            using System;
            using System.Collections;
            using System.Collections.Generic;

            namespace YieldTest
            {
                class Program
                {
                    static void Main(string[] args)
                    {
                        YieldString ys = new YieldString();
                        foreach (string s in ys)
                        {
                            Console.WriteLine(s);
                        }
                        foreach (string s in ys.Next())
                        {
                            Console.WriteLine(s);
                        }
                        Console.ReadKey();
                    }
                }

                class YieldString
                {
                    private string[] strs = new string[] { "Hello", "World", "!" };

                    public IEnumerator GetEnumerator()
                    {
                        foreach (string s in strs)
                        {
                            yield return s;
                        }
                    }

                    public IEnumerable Next()
                    {
                        foreach (string s in strs)
                        {
                            yield return s;
                        }
                    }
                }
            }

            internal class YieldString
            {
                // Fields
                private string[] strs = new string[] { "Hello", "World", "!" };

                // Methods
                public IEnumerator GetEnumerator()
                {
                    foreach (string iteratorVariable0 in this.strs)
                    {
                        yield return iteratorVariable0;
                    }
                }

                public IEnumerable Next()
                {
                    foreach (string iteratorVariable0 in this.strs)
                    {
                        yield return iteratorVariable0;
                    }
                }

                // Nested Types
                [CompilerGenerated]
                private sealed class <GetEnumerator>d__0 : IEnumerator<object>, IEnumerator, IDisposable
                {
                    // Fields
                    private int <>1__state;
                    private object <>2__current;
                    public YieldString <>4__this;
                    public string[] <>7__wrap3;
                    public int <>7__wrap4;
                    public string <s>5__1;

                    // Methods
                    [DebuggerHidden]
                    public <GetEnumerator>d__0(int <>1__state)
                    {
                        this.<>1__state = <>1__state;
                    }

                    private void <>m__Finally2()
                    {
                        this.<>1__state = -1;
                    }

                    private bool MoveNext()
                    {
                        try
                        {
                            switch (this.<>1__state)
                            {
                                case 0:
                                    this.<>1__state = -1;
                                    this.<>1__state = 1;
                                    this.<>7__wrap3 = this.<>4__this.strs;
                                    this.<>7__wrap4 = 0;
                                    while (this.<>7__wrap4 < this.<>7__wrap3.Length)
                                    {
                                        this.<s>5__1 = this.<>7__wrap3[this.<>7__wrap4];
                                        this.<>2__current = this.<s>5__1;
                                        this.<>1__state = 2;
                                        return true;
                                    Label_0079:
                                        this.<>1__state = 1;
                                        this.<>7__wrap4++;
                                    }
                                    this.<>m__Finally2();
                                    break;

                                case 2:
                                    goto Label_0079;
                            }
                            return false;
                        }
                        fault
                        {
                            this.System.IDisposable.Dispose();
                        }
                    }

                    [DebuggerHidden]
                    void IEnumerator.Reset()
                    {
                        throw new NotSupportedException();
                    }

                    void IDisposable.Dispose()
                    {
                        switch (this.<>1__state)
                        {
                            case 1:
                            case 2:
                                this.<>m__Finally2();
                                break;
                        }
                    }

                    // Properties
                    object IEnumerator<object>.Current
                    {
                        [DebuggerHidden]
                        get
                        {
                            return this.<>2__current;
                        }
                    }

                    object IEnumerator.Current
                    {
                        [DebuggerHidden]
                        get
                        {
                            return this.<>2__current;
                        }
                    }
                }

                [CompilerGenerated]
                private sealed class <Next>d__6 : IEnumerable<object>, IEnumerable, IEnumerator<object>, IEnumerator, IDisposable
                {
                    // Fields
                    private int <>1__state;
                    private object <>2__current;
                    public YieldString <>4__this;
                    public string[] <>7__wrap9;
                    public int <>7__wrapa;
                    private int <>l__initialThreadId;
                    public string <s>5__7;

                    // Methods
                    [DebuggerHidden]
                    public <Next>d__6(int <>1__state)
                    {
                        this.<>1__state = <>1__state;
                        this.<>l__initialThreadId = Thread.CurrentThread.ManagedThreadId;
                    }

                    private void <>m__Finally8()
                    {
                        this.<>1__state = -1;
                    }

                    private bool MoveNext()
                    {
                        try
                        {
                            switch (this.<>1__state)
                            {
                                case 0:
                                    this.<>1__state = -1;
                                    this.<>1__state = 1;
                                    this.<>7__wrap9 = this.<>4__this.strs;
                                    this.<>7__wrapa = 0;
                                    while (this.<>7__wrapa < this.<>7__wrap9.Length)
                                    {
                                        this.<s>5__7 = this.<>7__wrap9[this.<>7__wrapa];
                                        this.<>2__current = this.<s>5__7;
                                        this.<>1__state = 2;
                                        return true;
                                    Label_0079:
                                        this.<>1__state = 1;
                                        this.<>7__wrapa++;
                                    }
                                    this.<>m__Finally8();
                                    break;

                                case 2:
                                    goto Label_0079;
                            }
                            return false;
                        }
                        fault
                        {
                            this.System.IDisposable.Dispose();
                        }
                    }

                    [DebuggerHidden]
                    IEnumerator<object> IEnumerable<object>.GetEnumerator()
                    {
                        if ((Thread.CurrentThread.ManagedThreadId == this.<>l__initialThreadId) && (this.<>1__state == -2))
                        {
                            this.<>1__state = 0;
                            return this;
                        }
                        return new YieldString.<Next>d__6(0) { <>4__this = this.<>4__this };
                    }

                    [DebuggerHidden]
                    IEnumerator IEnumerable.GetEnumerator()
                    {
                        return this.System.Collections.Generic.IEnumerable<System.Object>.GetEnumerator();
                    }

                    [DebuggerHidden]
                    void IEnumerator.Reset()
                    {
                        throw new NotSupportedException();
                    }

                    void IDisposable.Dispose()
                    {
                        switch (this.<>1__state)
                        {
                            case 1:
                            case 2:
                                this.<>m__Finally8();
                                break;
                        }
                    }

                    // Properties
                    object IEnumerator<object>.Current
                    {
                        [DebuggerHidden]
                        get
                        {
                            return this.<>2__current;
                        }
                    }

                    object IEnumerator.Current
                    {
                        [DebuggerHidden]
                        get
                        {
                            return this.<>2__current;
                        }
                    }
                }
            }

            Feedback

            # re: 可枚舉對(duì)象與枚舉器  回復(fù)  更多評(píng)論   

            2015-08-01 14:28 by Onway
            為什么反編譯出來(lái)的MoveNext方法是private級(jí)別的呢?
            久久天天躁狠狠躁夜夜2020老熟妇| 久久亚洲欧洲国产综合| 欧美麻豆久久久久久中文| 一级做a爱片久久毛片| 精品久久久久久亚洲精品| 亚洲AV无码久久精品狠狠爱浪潮| 亚洲精品乱码久久久久久蜜桃| 久久久精品波多野结衣| 久久久中文字幕日本| 日本精品久久久久影院日本| 亚洲一级Av无码毛片久久精品| 亚洲伊人久久成综合人影院 | 久久亚洲AV无码西西人体| 国产呻吟久久久久久久92| 久久精品综合一区二区三区| 久久人人爽人人精品视频| 久久精品国产一区二区三区不卡| 久久综合久久鬼色| 区久久AAA片69亚洲| 人妻无码αv中文字幕久久琪琪布| 亚洲AV日韩精品久久久久久| 久久精品国产亚洲AV嫖农村妇女 | 国产精品日韩深夜福利久久 | 亚洲精品乱码久久久久久蜜桃| 久久国内免费视频| 久久无码人妻一区二区三区| 粉嫩小泬无遮挡久久久久久| 青青青伊人色综合久久| 日本精品一区二区久久久| 午夜天堂av天堂久久久| 久久国产亚洲精品麻豆| 精品国产热久久久福利| 久久久久久久久久久久久久| 久久精品国产亚洲av影院| 精品99久久aaa一级毛片| 蜜桃麻豆WWW久久囤产精品| 2020久久精品国产免费| 久久无码一区二区三区少妇| 久久综合狠狠综合久久| 免费观看久久精彩视频| 久久综合亚洲鲁鲁五月天|