C#之迭代器

要了解迭代器是干什么的,首先要了解为什么要用迭代
使用foreach的条件是可枚举集合,如果不是,会报错,所以要实现IEnumerable接口,使得可以使用foreach,但为了减轻程序员的工作量,提供了迭代器来完成工作。
以下代码只有加粗部分工作。
IEnumerator IEnumerable.GetEnumerator()
{
//通过手写枚举类型实现
// return new TreeEnumerator(this);
throw new NotImplementedException();
/* //通过迭代器来实现枚举
if (this.LeftTree != null)
{
foreach (TItem item in this.LeftTree)
{
yield return item;
}

        }
        yield return this.NodeData;
        if (this.RightTree != null)
        { 
        foreach (TItem item in this.RightTree )
        {
        yield return item ;

        }
        }
        */
    }

    调用代码为如下,目的是为了循环输出一个int型树的集合

        Tree<int> tree1 = new Tree<int>(10);
        tree1.Insert(2);
        tree1.Insert(4);
        tree1.Insert(222);
        foreach (int item in tree1)
        {
            Console.WriteLine(item);
        }
        ![这里写图片描述](https://img-blog.csdn.net/20170609195119891?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvU3cxMzE2OTY0MjYyMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
        结果是报错了。
        自己写一个枚举型,如下
        using System;

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BinaryTree
{
class TreeEnumerator:IEnumerator where TItem :IComparable
{
private Tree currentData = null;
private TItem currentItem = default(TItem);
private Queue enumData = null;
public TreeEnumerator(Tree data)
{
this.currentData = data;
}
private void populate(Queue enumQuene, Tree tree)
{
if (tree.LeftTree != null)
{
populate(enumQuene, tree.LeftTree);

        }
        enumQuene.Enqueue(tree.NodeData );
        if (tree.RightTree != null)
        {
            populate(enumQuene, tree.RightTree);
        }

    }



    TItem IEnumerator<TItem>.Current
    {
        get {

            if (this.enumData == null)
            {
                throw new InvalidOperationException("Use MoveNext before calling Current");
            }
            return this.currentItem; 
        }
    }

    void IDisposable.Dispose()
    {
     //   throw new NotImplementedException();
    }

    object System.Collections.IEnumerator.Current
    {
        get 
        {
            throw new NotImplementedException();
        }
    }

    bool System.Collections.IEnumerator.MoveNext()
    {
        if (this.enumData == null)
        {
            this.enumData = new Queue<TItem>();
            populate(this.enumData, this.currentData);
        }
        if (this.enumData.Count > 0)
        {
            this.currentItem = this.enumData.Dequeue();
            return true;
        }
        return false;
    }

    void System.Collections.IEnumerator.Reset()
    {
        throw new NotImplementedException();
    }
}

}
结果是可以运行的
这里写图片描述

但是看上图很明显这是一个很麻烦的工作,所以有了迭代器来减轻程序员的负担。以 yield关键字来解决问题。
if (this.LeftTree != null)
{
foreach (TItem item in this.LeftTree)
{
yield return item;
}

        }
        yield return this.NodeData;
        if (this.RightTree != null)
        { 
        foreach (TItem item in this.RightTree )
        {
        yield return item ;

        }
        每一次运行到yield,程序都会把结果送出去,并等待下一次调用这程序,下一次调用时会接着上一次调用的结果。
        ![这里写图片描述](https://img-blog.csdn.net/20170609195850217?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvU3cxMzE2OTY0MjYyMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
        结果和自己写的一样,但实现过程被大大简化了。
        最后附上树的代码:
        using System;

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BinaryTree
{
public class Tree:IEnumerable where TItem :IComparable
{
public TItem NodeData { get; set; }
public Tree LeftTree { get; set; }
public Tree RightTree { get; set; }
public Tree(TItem nodeValue)
{
this.NodeData = nodeValue;
this.LeftTree = null;
this.RightTree = null;
}
public void Insert(TItem newItem)
{
//插入一个数据项,如果大于当前值,插入左侧,否则插入右侧
TItem currentNodeValue = this.NodeData;
if (currentNodeValue.CompareTo(newItem) > 0)
{
if (this.LeftTree == null)
{
this.LeftTree = new Tree(newItem);
}
else
{

                this.LeftTree.Insert(newItem);
            }
        }
        else
        {
            if (this.RightTree == null)
            {
                this.RightTree = new Tree<TItem>(newItem);
            }
            else
            {
                this.RightTree.Insert(newItem);
            }

        }
    }
    public String WalkTree()
    { 
    //历遍Tree
        String result = "";
        if (this.LeftTree != null)
        {
            result = this.LeftTree.WalkTree()+" ";
        }
        result += String.Format("{0}", this.NodeData.ToString())+" ";
        if (this.RightTree != null)
        {
            result += this.RightTree.WalkTree()+" ";
        }
        return result;
    }


    IEnumerator<TItem> IEnumerable<TItem>.GetEnumerator()
    {
        //通过手写枚举类型实现
       // return new TreeEnumerator<TItem>(this);
       //throw new NotImplementedException();
        //通过迭代器来实现枚举
        if (this.LeftTree != null)
        {
            foreach (TItem item in this.LeftTree)
            {
                yield return item;
            }

        }
        yield return this.NodeData;
        if (this.RightTree != null)
        { 
        foreach (TItem item in this.RightTree )
        {
        yield return item ;

        }
        }






    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值