2021年6月26日 星期六

C# yield return 疊代器模式

有一個題目請印出1~100

使用for來解
 
for (int i = 1; i <= 100; i++)
{
    Console.WriteLine("Number: {0}", i);
}

這樣寫沒什麼毛病,簡單明瞭
若改成印出 1~100 之中,2 或 3 的倍數

 
for (int i = 1; i <= 100; i++)
{
    bool match = false;

    if (i % 2 == 0) match = true;
    if (i % 3 == 0) match = true;

    if (match == true)
    {
        Console.WriteLine("Number: {0}", i);
    }
}

 好像for裡面沒這麼乾淨了,若之後邏輯更複雜,可想而知後面修改的人看到這個迴圈
可能會去填離職單,所以這時候可以使用Iterator Pattern(疊代器模式)來把邏輯包起來寫法如下

 
public class Example : IEnumerator
    {
        private int _start = 1;
        private int _end = 100;
        private int _current;
        public Example(int start, int end)
        {
            this._start = start;
            this._end = end;
            this.Reset();
        }

        public object Current
        {
            get { return this._current; }
        }

        public bool MoveNext()
        {
            this._current++;
            bool match = false;            
            if (this._current % 2 == 0) match = true;
            if (this._current % 3 == 0) match = true;
            return match;
        }

        public void Reset()
        {
            this._current = 0;
        }
    }

使用方法如下
 
Example e = new Example(1, 100);
while (e.MoveNext())
{
    Console.WriteLine("Number: {0}", e.Current);
}

這樣寫的好處是你完全不需要知道實作的邏輯,你只要相信類別給你的數字顯示即可
程式碼也變得很好閱讀,也非常的乾淨,但是每次都要叫你實作Iterator Pattern
都要寫一大坨類別實作,真的也是滿累的
所以在這邊要介紹一下c#的yield return
若改成yield return會變成怎樣呢,請看以下實作

 
public static IEnumerable<int> yieldExample(int start, int end)
        {
            for (int i = 1; i <= 100; i++)
            {
                bool match = false;

                if (i % 2 == 0) match = true;
                if (i % 3 == 0) match = true;

                if (match == true)
                {
                    yield return i;
                }
            }
        }

如何使用呢
 
public void Example()
        {
            foreach (var current in yieldExample(1, 100))
            {
                Console.WriteLine("Current Number: {0}", current);
            }
        }

挖靠c#居然有這麼好用的東西

沒有留言:

張貼留言