zoukankan      html  css  js  c++  java
  • 使用迭代器优化代码

    案例一:

        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
  • 相关阅读:
    android Context 持有导致的内存泄漏
    android PreferenceFragment
    android 修改 SwitchPreferenceCompat 高度,内边距,字体大小
    Android MPAndroidChart RadarChart (蜘蛛网图)
    Bugtags 测试平台(支持ios、android)
    BlockCanary 一个轻量的,非侵入式的性能监控组件(阿里)
    RecyclerView item 状态错乱
    RecyclerView android:layout_width="match_parent" 无效
    android-async-http cancelRequests
    Android MultiDex
  • 原文地址:https://www.cnblogs.com/refuge/p/8646579.html
Copyright © 2011-2022 走看看