使用迭代器优化代码

案例一:

    public class Order
    {

        public DateTime StartDate { get; set; }


        public DateTime EndDate { get; set; }


        public IEnumerable<DateTime> DateRange
        {
            get
            {
                for (DateTime day = StartDate; day <= EndDate; day = day.AddDays(1))
                {
                    yield return day;
                }
            }
        }
    }

 

            Order order = new Order
            {
                StartDate = DateTime.Now,
                EndDate = DateTime.Now.AddDays(31)
            };


            #region 不使用迭代器

            for (DateTime day = order.StartDate; day <= order.EndDate; day = day.AddDays(1))
            {
                Console.WriteLine(day);
            }

            #endregion


            Console.WriteLine("********************************************");


            #region 使用迭代器

            foreach (var dateTime in order.DateRange)
            {
                Console.WriteLine(dateTime);
            }

            #endregion

 

案例二:

    class Program
    {
        static void Main(string[] args)
        {
            string path = "";
            using (TextReader reader = File.OpenText(path))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    Console.WriteLine(line);
                }
            }
        
       //下面是对上面这段代码的封装
#region 版本1 TextReader tr = File.OpenText(path); ReadFile(tr, Console.WriteLine);// ,这里之所以可以这样简写委托实例,是因为 Console.WriteLine() 方法有很多重载,利用了 "Method Group"的概念 #endregion #region 版本2 foreach (var line in ReadLines(path)) { Console.WriteLine(line); } #endregion Console.ReadKey(); } #region 版本1 static void ReadFile(TextReader reader, Action<string> action) { string line; while ((line = reader.ReadLine()) != null) { action(line); } reader.Close(); reader.Dispose(); } #endregion //这个版本的弊端是:reader 在方法内部创建,限制了编码格式,如果调用者突然想用其他编码方式,则无法使用该方法 #region 版本2 static IEnumerable<string> ProcessFile(string path) { using (TextReader reader = File.OpenText(path)) { string line; while ((line = reader.ReadLine()) != null) { yield return line; } } } #endregion //如果我们想使用不用的编码格式呢? //所以 reader 的创建还是要交换给调用者 //但是这个方案最大的弊端是:需要调用者自己清理 reader #region 版本3 static IEnumerable<string> ReadLines(TextReader reader) { string line; while ((line = reader.ReadLine()) != null) { yield return line; } } #endregion //利用委托,延迟 reader 的创建 //即,我们只有在需要的时候才去获取资源 #region 终极版本 static IEnumerable<string> ReadLines(Func<TextReader> provider) { using (TextReader reader = provider()) { string line; while ((line = reader.ReadLine()) != null) { yield return line; } } } static IEnumerable<string> ReadLines(string path) { return ReadLines(path, Encoding.UTF8); } static IEnumerable<string> ReadLines(string path, Encoding encoding) { return ReadLines(() => new StreamReader(path, encoding)); } #endregion }

 

案例三:

 

    class Program
    {
        static void Main(string[] args)
        {
            List<int> list = new List<int> { 1, 2, 3, 4, 5, 6, 7 };


            //当我们调用 where 方法时,我们理所当然的认为会立刻进行参数的校验
            //但实际上不是,因为在 where 方法里面有 yield return 语句,也就是说:这个 where 方法是一个迭代器块
            //而迭代器块具有延迟执行的特性
            //意思就是,当我们调用 where 方法的时候,并不会立刻执行方法内部的参数校验,
            //而是要等到 foreach 语句的 in 指令时,才会执行
            //同时,由于 yield return 语句返回的类型必须是实现了 IEnumerable 或者 IEnumerable<T> 接口的类型         

            var result = WhereGood(list, s => s % 2 == 0);

            foreach (var i in result)
            {
                Console.WriteLine(i);
            }

            Console.ReadKey();
        }


        #region 不好的写法

        static IEnumerable<T> Where<T>(IEnumerable<T> source, Predicate<T> predicate)
        {
            if (source == null || predicate == null)
            {
                Console.WriteLine("入参错误!");
                throw new Exception("入参错误");
            }

            foreach (var item in source)
            {
                if (predicate(item))
                {
                    yield return item;
                }
            }
        }

        #endregion


        #region 好的写法,校验参数和逻辑代码分开写

        static IEnumerable<T> WhereGood<T>(IEnumerable<T> source, Predicate<T> predicate)
        {
            if (source == null || predicate == null)
            {
                Console.WriteLine("入参错误!");
                throw new Exception("入参错误");
            }

            //同样,这里不会立刻执行 GoWhere() 方法,直到 执行到 foreach 中的 in
            return GoWhere(source, predicate);
        }


        static IEnumerable<T> GoWhere<T>(IEnumerable<T> source, Predicate<T> predicate)
        {
            foreach (var item in source)
            {
                if (predicate(item))
                {
                    yield return item;
                }
            }
        }

        #endregion

 

转载于:https://www.cnblogs.com/refuge/p/8646579.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值