码迷,mamicode.com
首页 > 编程语言 > 详细

C# 通过IEnumberable接口和IEnumerator接口实现自定义集合类型foreach功能

时间:2017-08-23 19:03:43      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:cep   blog   tor   定义   方法   理解   rgs   位置   tle   

1、IEnumerator和IEnumerable的作用

其实IEnumerator和IEnumerable的作用很简单,就是让除数组和集合之外的类型也能支持foreach循环,至于foreach循环,如果不清楚,请参考C# foreach循环较for循环的优势与劣势

代码如下:

static void Main(string[] args)
{
       CatList cats = new CatList();
       foreach (var cat in cats)
       {
            Console.WriteLine(cat.NickName);
       }
}

public class CatList
{
       public string NickName { get; set; }
       public int Age { get; set; }
}

技术分享

以上代码说明自定义集合类型(假设CatList是集合类型)是无法使用foreach进行循环的.

原因是C#中自定义集合类型要实现foreach的功能,必须通过IEnumerator和IEnumerable两个接口来实现!

 

2、通过IEnumerator和IEnumerable两个接口实现自定义集合类型的foreach循环功能.

第一步:实现自定义集合类型实现IEnumerable接口,实现该接口的字面意思可以理解为:自定义集合类型实现了该接口,就拥有了"可枚举的功能".代码如下:

技术分享

实现了IEnumerable接口之后,发现该接口规定必须返回一个IEnumerator接口(迭代器对象).ok,那么就必须返回一个IEnumerator,那么它是什么呢?别急,下面开始介绍这个接口!

 

第二步:通过IEnumerable要求实现的GetEnumerator()方法返回一个IEnumerator(迭代器对象),实现该接口必须实现以下三个方法/属性:

技术分享

(1)、MoveNext()   ---将当前遍历的枚举数推进到集合的下一个.

注:如果 MoveNext 越过集合的末尾,则枚举数将被放置在此集合中最后一个元素的后面,而且 MoveNext 返回 false。当枚举数位于此位置时,对MoveNext 的后续调用也返回 false。如果最后一次调用 MoveNext 返回 false,则调用 Current 会引发异常。若要再次将 Current 设置为集合的第一个元素,可以调用 Reset,然后再调用 MoveNext

 

(2)、Current属性   ---返回正在遍历的集合中的元素

(3)、Reset()   ---重置当前正在遍历的集合中元素的索引.

 

第三步:具体实现

在介绍完上面两个接口之后,开始具体的实现,现在需要编写一个People类,该类是一个Person集合,要求People类拥有foreach循环的功能,代码如下:

        /// <summary>
        /// 自定义集合类,要求能进行foreach循环
        /// </summary>
        public class People : IEnumerable
        {
            private Person[] _persons;

            public People(Person[] persons)
            {
                this._persons = persons;
            }

            public IEnumerator GetEnumerator()
            {
                return new PersonEnum(_persons);
            }

            private class PersonEnum : IEnumerator
            {
                private Person[] _perons;
                private int _position;
                public PersonEnum(Person[] persons) 
                {
                    this._perons = persons;
                }

                public object Current
                {
                    get {
                        try
                        {
                            return _perons[_position]; 
                        }
                        catch (IndexOutOfRangeException)
                        {
                            throw new IndexOutOfRangeException();
                        }
                    }
                }

                public bool MoveNext()
                {
                    return (_position < _perons.Length);
                }

                public void Reset()
                {
                    _position = 0;
                }
            }
        }

        public class Person
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
        }

 

第四步:验证代码,代码如下:

Person[] persons ={
         new Person(){FirstName="Stephen",LastName="Curry"},
         new Person(){FirstName="Lebron",LastName="James"},
         new Person(){FirstName="Kobe",LastName="Brant"}
};
People people = new People(persons);
foreach (var p in people)
{
     Console.WriteLine(((Person)p).LastName);
}

 

C# 通过IEnumberable接口和IEnumerator接口实现自定义集合类型foreach功能

标签:cep   blog   tor   定义   方法   理解   rgs   位置   tle   

原文地址:http://www.cnblogs.com/GreenLeaves/p/7419541.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!