使用foreach语句对类似于集合的类中的成员进行枚举

本文介绍了如何在C#中为自定义的集合类支持foreach语句,包括C#2.0引入的泛型和yield return语句的应用,使得迭代过程更加便捷高效。
摘要由CSDN通过智能技术生成

--------------------------------------------------------------------------------------------------------------------

如果你正在创建一个表现和行为都类似于集合的类(自定义ListBox类),允许类的用户使用foreach语句对类似集合的类中的成员进行枚举将会是很方便的。那么真对一个类似于集合的类,我们应该怎么使用foreach 语句呢?

   想要使用foreach语句,必须实现IEnumerable 接口。
   这个接口只要求实现一个方法: GetEnumerator。这个方法必须返回一个实现了IEnumerator 接口的对象(注意: IEnumerable 和 IEnumerator 是不同的接口,请不要搞混了)。除此以外,我们需要返回的这个对象不仅实现了IEnumerator,而且知道如何枚举ListBox对象。
因此,实现IEnumerator接口的最好办法是在实现IEnumerable的类里创建一个嵌套的IEnumerator类(ListBoxEnumerator类)。
namespace Test
{
    public class ListBox:IEnumerable
    {
        private string[] strings;
        private int ctr;
        private int ctr0;
        public string this[int x]
        {
            get
            {
                try
                {
                    return strings[x];
                }
                catch (Exception ex)
                {
                    return ex.ToString();
                }   
                
            }
        }
        private class myListBoxEnumerator : IEnumerator
        {
            private ListBox lbt;
            private int index;

            public myListBoxEnumerator(ListBox lbt)
            {
                this.lbt = lbt;
            }
            //实现IEnumerator接口
            #region 实现IEnumerator接口
            public object Current
            {
                get { return (lbt[index++]); }
            }

            public bool MoveNext()
            {
                //index;
                if (index >= lbt.strings.Length)
                {
                    return false;
                }
                else
                {
                    return true;
                }

            }

            public void Reset()
            {
                index = -1;
            }
            #endregion

        }

        //这个方法必须返回一个实现了IEnumerator 接口的对象
        public IEnumerator GetEnumerator()
        {
            return new myListBoxEnumerator(this);
        }

       
       

        public ListBox(params string[] initialStrings)
        {
            strings = new String[8];
            
            foreach (string s in initialStrings)
            {
                strings[ctr++] = s;
            }
        }
        public void Add(string theString)
        {
            strings[ctr] = theString;
            ctr++;
        }
        public int GetNumEntries()
        {
            return ctr;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            ListBox lbt = new ListBox("Hello", "World");
            lbt.Add("Who");
            lbt.Add("Is");
            lbt.Add("John");
            lbt.Add("Galt");
            foreach (string s in lbt)
            {
                Console.WriteLine("Value: {0}", s);
                
            }
            Console.ReadLine();
        }
    }
}


C#2.0以后

1、用泛型解决了Current属性返回一个Object对象;2、不需要为每个类型实现你自己的IEnumerator,不需要创建嵌套类。

namespace Test
{
    public class ListBox:IEnumerable<string>
    {
        private string[] strings;
        private int ctr;
        private int ctr0;
        public string this[int x]
        {
            get
            {
                try
                {
                    return strings[x];
                }
                catch (Exception ex)
                {
                    return ex.ToString();
                }   
                
            }
        }
 

        public ListBox(params string[] initialStrings)
        {
            strings = new String[8];
            
            foreach (string s in initialStrings)
            {
                strings[ctr++] = s;
            }
        }
        public void Add(string theString)
        {
            strings[ctr] = theString;
            ctr++;
        }
        public int GetNumEntries()
        {
            return ctr;
        }

        //这个方法必须返回一个实现了IEnumerator 接口的对象
        public IEnumerator<string> GetEnumerator()
        {
            while (ctr0 < this.strings.Length)
            {
                yield return this[ctr0++];
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            ListBox lbt = new ListBox("Hello", "World");
            lbt.Add("Who");
            lbt.Add("Is");
            lbt.Add("John");
            lbt.Add("Galt");
            foreach (string s in lbt)
            {
                Console.WriteLine("Value: {0}", s);
                
            }
            Console.ReadLine();
        }
    }
}

yield语句。

yield return <expression>;
yield break;

您使用 yield return 语句每一次返回每个元素。

将使用 foreach 语句从客户端代码中调用迭代器。 foreach 循环的每次迭代都会调用迭代器方法。 迭代器方法运行到 yield return 语句时,会返回一个expression表达式并保留当前在代码中的位置。 当下次调用迭代器函数时执行从该位置重新启动。

您可以用 yield break语句来终止迭代。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值