zoukankan      html  css  js  c++  java
  • 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;
    }

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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方法完成吧!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    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扩展方法。答案在文章末尾。

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

    练习题答案

    1
    2
    3
    4
    5
    6
    7
    8
    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;
        }
    }

      

  • 相关阅读:
    Web服务器和应用服务器的区别
    Java程序员应该知道的10个调试技巧
    java快捷键个人总结
    MySQL主从复制与读写分离
    CDN(内容分发网络)技术原理
    淘宝技术发展
    Monitor a Folder using Java
    Android eclipse中程序调试
    在学校教学Java是有争议的
    LINUX ubuntu 12.04 svn 1.6.7 苦逼的装了一个下午啊!! 绝对详细!正确!不吭爹!!
  • 原文地址:https://www.cnblogs.com/zhangxiaolei521/p/5552166.html
Copyright © 2011-2022 走看看