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;
                    }
                }
            }
        }
    
    
    }
  • 相关阅读:
    【转】 url中文乱码问题
    [转]Jquery 点击图片在弹出层显示大图
    JQuery获取和设置Select选项的常用方法总结
    springMVC框架下返回json格式的对象,list,map
    sqlserver数据库 表中字段值有空格,如何去除空格(例如char (5) 存入数据不足5位时sqlserver会自动补空格)
    jquery Jbox 插件实现弹出窗口在修改的数据之后,关闭弹出窗口刷新父页面的问题
    sqlserver 2008 r2 直接下载地址,可用迅雷下载
    web服务器与tomcat
    xml入门与解析
    jdbc框架-dbutils的简单使用
  • 原文地址:https://www.cnblogs.com/lgxlsm/p/6758150.html
Copyright © 2011-2022 走看看