• 1.解剖Linq to object


      LINQ想必大家都不陌生了,它的出现使得我们的代码变得更短、更优雅了。至于LINQ是什么,Linq to object这类的扩展方法到底做了些什么。我们使用的EF是如何实现的(如何解析Expression)。我都将一一为大家分享下我的理解。如果有说得不对的地方,也请大家指出。下面进入正题

    大家先将代码左上角的using System.Linq去掉

    当我们想对一个集合的数据进行筛选的时候,我们以前会这样做

            static void Main(string[] args)
            {
                List<int> list = new List<int>()
                {
                    2,3,6,4,7,8
                };
    
                List<int> result = new List<int>();
                foreach (var item in list)
                {
                    if (item < 4)
                    {
                        result.Add(item);
                    }
                }
            }
    

      

    但我们仔细想想,我们要筛选数据时,就一定要遍历它,所以循环这部份是必须的。还有什么是必须的呢?筛选条件!筛选数据时筛选的条件是不同的,但它们有个共同的特点,那就是条件的结果不是true就是false。既然有这么多的共同点,我们能不能把它抽象出来写成一个通用的扩展方法供我们调用呢?聪明的你估计已经想到这个方法大概要怎样构造了。这个方法的参数有2个,一个是我们要进行数据筛选的集合,另一个是我们的筛选条件。方法体里面要做的就是去遍历这个集合,当满足筛选条件时,我们就把这个元素存到结果集合中,最后返回结果集合。想必完成后的代码是这样的

            public static List<int> Where(List<int> list, Func<int, bool> func)
            {
                List<int> result = new List<int>();
                foreach (int item in list)
                {
                    bool istrue = func(item);//执行我们的筛选函数
                    if (istrue)//如果满足筛选条件,就添加进result集合中
                    {
                        result.Add(item);
                    }
                }
                return result;
            }

    这时我们就可以这样进行数据筛选了,是不是清爽简洁了很多?

            static void Main(string[] args)
            {
                List<int> list = new List<int>()
                {
                    2,3,6,4,7,8
                };
                var result = Where(list, x => x < 4);
                var result2 = Where(list, x => x / 2 == 0);
            }
    

      

    但问题来了。我们的方法只支持List<int>啊,如果换成int[]就不行了。怎么解决呢?仔细想想我们只需要遍历它就可以了,不需要对它操作啊,想到遍历想到什么?foreach!想到foreach想到什么?IEnumerable!不多说。马上搞起。修改后应该变成这样

            static void Main(string[] args)
            {
                List<int> list = new List<int>()
                {
                    2,3,6,4,7,8
                };
                int[] array = list.ToArray();
                var result = Where(array, x => x < 4);
                var result2 = Where(list, x => x / 2 == 0);
            }
    
            public static IEnumerable<int> Where(IEnumerable<int> list, Func<int, bool> func)
            {
                foreach (int item in list)
                {
                    bool istrue = func(item);
                    if (istrue)
                    {
                        yield return item;
                    }
                }
            }
    

      

    看似已经完成了,但我们往细的想想,我们的方法只支持int类型,我们想把它变成通用的,任何类型都支持。这时我们想到什么?没错,泛型。。

    还有,我们平时都是list.Where(条件)来调用的。相信很多同学都知道吧,这种叫做扩展方法。我们如何改呢?下面让我们来一口把这个Where方法完成吧!

        class Program
        {
            static void Main(string[] args)
            {
                List<int> list = new List<int>()
                {
                    2,3,6,4,7,8
                };
                int[] array = list.ToArray();
                array.Where(x => x > 0);
                list.Where(x => x / 2 == 0);
            }
        }
    
        public static class MyLinq
        {
            public static IEnumerable<T> Where<T>(this IEnumerable<T> list, Func<T, bool> func)
            {
                foreach (T item in list)
                {
                    bool istrue = func(item);
                    if (istrue)
                    {
                        yield return item;
                    }
                }
            }
        }
    

      

    小贴士:扩展方法就是静态类中的静态方法,参数有this xxx。这个静态类不能是内部类

    想必大家现在对LINQ有了一定的认识了吧?看完后是不是觉得LINQ其实就那么回事呢?看完后也要做下练习来巩固下吧。下面请大家自行完成一个Select扩展方法。答案在文章末尾。

    这也是我第一篇博文,写的时候手都在抖,怕表达不清或说错了什么误导了大家。很早就开始想写博文了,但都太忙了。现在总算有个开始了

    练习题答案

            public static IEnumerable<TResult> Select<TInput, TResult>(this IEnumerable<TInput> list, Func<TInput, TResult> func)
            {
                foreach (TInput item in list)
                {
                    TResult result = func(item);
                    yield return result;
                }
            }
    

      

  • 相关阅读:
    JDBC 复习4 批量执行SQL
    JDBC 复习3 存取Oracle大数据 clob blob
    Oracle复习
    Linux命令(1)grep
    JDBC 复习2 存取mysql 大数据
    JDBC 复习1 DBUtil
    php 环境搭建问题
    Windows 批处理 bat 开启 WiFi 菜单选项 设置ID PWD
    Bat 批处理启动和停止Oracle 服务
    docker 学习1 WSL docker ,Windows docker
  • 原文地址:https://www.cnblogs.com/irenebbkiss/p/4155480.html
Copyright © 2020-2023  润新知