zoukankan      html  css  js  c++  java
  • IEnumerable和IEnumerator接口

    我们先思考几个问题:
    1.为什么在foreach中不能修改item的值?(IEnumerator的Current为只读)
    2.要实现foreach需要满足什么条件?(实现IEnumerator接口来实现的)
    3.为什么Linq to Object中要返回IEnumerable?(因为IEnumerable是延迟加载的,每次访问的时候才取值。也就是我们在Lambda里面写的where、select并没有循环遍历(只是在组装条件),只有在ToList或foreache的时候才真正去集合取值了。这样大大提高了性能。)

    .net中迭代器是通过IEnumerable和IEnumerator接口来实现的,今天我们也来依葫芦画瓢。

    using System;
    using System.Collections;
    
    namespace RedisTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                string[] str = { "1111", "2222", "3333", "4444", "5555" };
                var aaa = new MyIEnumerable(str);
                var bbb = aaa.GetEnumerator();
                while (bbb.MoveNext())
                {
                    Console.WriteLine(bbb.Current);
                }
                Console.WriteLine("---------------------------------------------------------");
                foreach (var item in aaa)
                {
                    Console.WriteLine(item);
                }
                Console.Read();
                /*
                1111
                2222
                3333
                4444
                5555
                ---------------------------------------------------------
                1111
                2222
                3333
                4444
                5555
                */
            }
        }
    
        public class MyIEnumerable : IEnumerable
        {
            private string[] strList;
            public MyIEnumerable(string[] _strList)
            {
                strList = _strList;
            }
            public IEnumerator GetEnumerator()
            {
                return new MyIEnumerator(strList);
            }
        }
    
        public class MyIEnumerator : IEnumerator
        {
            private string[] strList;
            private int position;
    
            public MyIEnumerator(string[] _strList)
            {
                strList = _strList;
                position = -1;
            }
            public object Current
            {
                get
                {
                    return strList[position];
                }
            }
    
            public bool MoveNext()
            {
                position++;
                if (position < strList.Length)
                    return true;
                return false;
            }
    
            public void Reset()
            {
                position = -1;
            }
        }
    }

    yield的使用

    using System;
    using System.Collections;
    
    namespace RedisTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                string[] str = { "1111", "2222", "3333", "4444", "5555" };
                var aaa = new MyIEnumerable(str);
                var bbb = aaa.GetEnumerator();
                while (bbb.MoveNext())
                {
                    Console.WriteLine(bbb.Current);
                }
                Console.WriteLine("---------------------------------------------------------");
                foreach (var item in aaa)
                {
                    Console.WriteLine(item);
                }
                Console.Read();
                /*
                1111
                2222
                3333
                4444
                5555
                ---------------------------------------------------------
                1111
                2222
                3333
                4444
                5555
                */
           
            }
        }
    
        public class MyIEnumerable
        {
            private string[] strList;
            public MyIEnumerable(string[] _strList)
            {
                strList = _strList;
            }
            public IEnumerator GetEnumerator()
            {
                for (int i = 0; i < strList.Length; i++)
                {
                    yield return strList[i];
                }
            }
        }
    
    
    }

    我们调用GetEnumerator的时候,看似里面for循环了一次,其实这个时候没有做任何操作。只有调用MoveNext的时候才会对应调用for循环:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace RedisTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                string[] str = { "1111", "2222", "3333", "4444", "5555" };
                var aaa = new MyIEnumerable(str);
                var bbb = aaa.MyWhere(x => x != "1111");
                var ccc = bbb.ToList();
                //现在看到了吧。执行到MyWhere的时候什么动作都没有(返回的就是IEnumerable),只有执行到ToList的时候才代码才真正的去遍历筛选。
                //这里的MyWhere其实可以用扩展方法来实现,提升逼格。(Linq的那些查询操作符就是以扩展的形式实现的)
                Console.Read();
    
    
            }
        }
    
        public class MyIEnumerable
        {
            private string[] strList;
            public MyIEnumerable(string[] _strList)
            {
                strList = _strList;
            }
            public IEnumerator GetEnumerator()
            {
                for (int i = 0; i < strList.Length; i++)
                {
                    yield return strList[i];
                }
            }
            public IEnumerable<string> MyWhere(Func<string, bool> func)
            {
                foreach (string item in this)
                {
                    if (func(item))
                    {
                        yield return item;
                    }
                }
            }
        }
    
    
    }
  • 相关阅读:
    Javascript图片轮播
    Javascript返回顶部
    Android Studio 中 Svn的使用
    js简介
    使用Androd Studio开发Andriod程序查看Sha1的方法
    VueJs学习路线
    Eclipse 项目导入 Studio Debug运行卡死在进入界面
    Node软件的安装
    TextView加边框,自定义,上下左右四条线 颜色,想用哪个用哪个
    安装Eclipse(android)新建项目时遇到的问题
  • 原文地址:https://www.cnblogs.com/lgxlsm/p/6758150.html
Copyright © 2011-2022 走看看