【C#函数式编程】C#中的函数式编程(二) —— IEnumerable和IEnumerator使用详解

一、IEnumerable接口

        IEnumerable接口可以暴露一个Celltions的元素的迭代器,它只含有一个方法GetEnumerator,这个方法返回一个IEnumerator对象,而通过这个IEnumerator对象,我们就可以遍历整个Celltions中的元素。

二、代码示例

        下面的代码,演示如何继承IEnumerable接口和IEnumerator接口,并通过继承IEnumerator实现用foreach遍历IEnumerator的派生类。首先我们先创建一个自定义的类对象Person用于作为集合对象的元素:

class Person
    {
        public Person(stringname)
        {
            this.name = name;
        }
        public string name;
    }

        接下来定义一个Person类的集合对象People,需要继承自IEnumerable接口,这个对象中必须实现GetEnumerator方法,我们在这个方法中返回一个IEnumerator的派生类PeopleEnum,而在这个派生类中将对需要遍历的People类对象进行封装,从而实现其遍历。

class People : IEnumerable    
{
        private Person[]_people;
        public People(Person[]pArray)
        {
           _people = new Person[pArray.Length];
            for (int i = 0; i< pArray.Length;i++)
            {
               _people[i] = pArray[i];
            }
        }
 
        //实现GetEnumerator方法
        IEnumerator IEnumerable.GetEnumerator()
        {
            return (IEnumerator)GetEnumerator();
        }
 
        public PeopleEnum  GetEnumerator()
        {
            return new PeopleEnum (_people);
        }
    }
        接下来我们还需要实现对GetEnumerator的继承,定义PeopleEnum 类:

class PeopleEnum : IEnumerator
    {
        public Person[]_people;
 
        int position = -1;
        public PeopleEnum(Person[]list)
        {
           _people = list;
        }
 
        public boolMoveNext()
        {
           position++;
            return position < _people.Length;
        }
      
        public void Reset()
        {
           position = -1;
        }
 
        object IEnumerator.Current
        {
            get
            {
               return Current;
            }
        }
        public PersonCurrent
        {
            get
            {
               try
               {
                   return _people[position];
               }
               catch (IndexOutOfRangeException)
               {
                   throw newInvalidOperationException();
               }
            }
        }
    }
        可以看到,我们定义的PeopleEnum中position表示指向当前集合元素的索引,而我们分别实现了MoveNext()、Reset()两个方法和Current属性。Current获取当前索引指向的集合元素,而MoveNext()将索引向后移动一位,Reset()将索引回到起始状态。
        经过了上面的实现,我们就可以直接用foreach迭代遍历People对象了:


 Person[] peopleArray = newPerson[3]
        {
            new Person("张?三¨y"),
            new Person("李¤?四?"),
            new Person("王ª?五?"),
        };
            People people = newPeople(peopleArray) { };
           
            foreach (var va in people)
            {
               Console.WriteLine(va.name);
            }

        实际上,使用foreach进行遍历时,无非就是调用People对象的GetEnumerator()方法,获取到了PeopleEnum对象。而后再调用PeopleEnum对象的MoveNext()、Reset()两个方法和Current属性实现遍历。即使我们的People和PeopleEnum不从IEnumerable和IEnumerator继承,只要实现了上述几种方法和属性,People对象同样也会被成功遍历。

三、其他继承了IEnumerable的C#内置类型

        C#中许多有集合意义的数据类型都继承了IEnumerable接口,比如Dictionary和List。通常情况下凡是采用foreach能够遍历的类型都是继承了IEnumerable接口,比如List<int>继承自IEnumerable<int>,Dictionary<int,string>继承自IEnumerable<int,string>。下面的代码就是利用Dictionary和List对象的GetEnumerator()方法,返回了一个Enumerator对象,再利用该对象进行遍历:

  Dictionary<int,string> dic = newDictionary<int,string>();
           dic.Add(1, "Tom");
           dic.Add(2, "Jerry");
           dic.Add(3, "Hyman");
 
            Dictionary<int,string>.Enumeratorenumerator = dic.GetEnumerator();
            for (int i = 0; i< dic.Count;i++ )
            {
               enumerator.MoveNext();
               Console.WriteLine(enumerator.Current.Value);
            }
 
            List<string>list = new List<string> { "123","456", "789"};
            List<string>.Enumerator enumerator2 = list.GetEnumerator();
            for (int j = 0; j< list.Count; j++)
            {
               enumerator2.MoveNext();
               Console.WriteLine(enumerator2.Current);
            }        

        最终结果如下:




Github位置:
https://github.com/HymanLiuTS/CSGroup
克隆本项目:
Git clone git@github.com:HymanLiuTS/ CSGroup.git
获取本文源代码:
git checkout CSL03



  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值