zoukankan      html  css  js  c++  java
  • LINQ学习心得分享(三)LINQ语法详解2

    接着上一节的讲,在这一节我会带领大家把剩余的一些LINQ语法给大家讲解完。好了,废话不多说,进入正题。

    1、CastOfType操作符

    CastOfType:都用于将一个类型为IEnumerable的集合对象转化为一个类型为IEnumerable<T>的集合对象,两者的功能都是一样的,唯一的区别在于Cast操作符进行类型转换时,如果转换中出现转化失败的情况,则会抛出一个异常,而OfTyoe操作符只是把能够转换的元素转换掉

    这里还是用上一节的例子:(该示例参考自Rookie_J博客)

    先新建一个ArrayList对象

               ArrayList  arraylist = new ArrayList()

                {

                new Person(){ Name="Olive",Sex="",Age=18},

                new Person(){ Name="Moyao",Sex="",Age=19},

                new Person(){ Name="Momo",Sex="",Age=20},

                new Person(){ Name="Only",Sex="",Age=21},

                new Profession() { Name = "Olive", ZhiYe = "会计" }, 

                new Profession() { Name = "Remote", ZhiYe = "IT Coder" }, 

                new Profession() { Name = "BLove", ZhiYe = "学生" },

                new Profession(){ Name="AFor",ZhiYe="作家"}

                };

                Console.WriteLine("人员信息表:");

    //arraylist对象转换为IEnumerable<person>对象

                IEnumerable<Person> pers= arraylist.OfType<Person>();

                foreach (var p in pers)

                {

                    Console.WriteLine("人员信息:"+p.Name+"  性别:"+p.Sex+"   年龄:"+p.Age);

                }

                Console.WriteLine("人员职业表:");

    //arraylist

                IEnumerable<Profession> professions = arraylist.OfType<Profession>();

                foreach (var p in professions)

                {

                    Console.WriteLine("人员姓名:" + p.Name + "   职业:" + p.ZhiYe);

                }

    结果:

    2、DefaultIfEmptyFirstOrDefault、LastOrDefault、SingleOrDefault、ElementAtOrDefault

    2.1DefaultIfEmpty:在查询不到所符合要求的信息时,返回一个含有默认元素的序列

     IEnumerable<Person> pers= arraylist.OfType<Person>();

                var defaultTest = pers.Where(p => p.Name == "").DefaultIfEmpty(new Person() { Name = "查无此人"});

                foreach(var p in defaultTest)

                {

                    Console.WriteLine("查询结果:" + p.Name);

                }

    结果:

    2.2FirstOrDefault/LastOrDefault:顾名思义,返回输出序列中满足条件的第一(最后一个)元素,如果没有,序列元素类型是引用类型的则返回null,是值类型的则返回该值类型的默认值

     Person defaultTest = pers.Where(p => p.Name == "Olive").FirstOrDefault();

                //foreach (var p in defaultTest)

                //{

                if (defaultTest != null)

                {

                    Console.WriteLine("FirstOrDefault查询结果:" + defaultTest.Name + "  " + defaultTest.Age + "   " +defaultTest.Sex);

                }

                else

                {

                    Console.WriteLine("FirstOrDefault查询结果:查无此人!");

                }

    结果:

    如果将Person defaultTest = pers.Where(p => p.Name == "").FirstOrDefault();

    则结果为:

     

    LastOrDefaultFirstOrDefault使用方法基本上都差不多,只不过LastOrDefault返回的是符合查询条件的序列的最后一个元素,如果没有的符合条件元素则返回默认值。

    2.3SingleOrDefault:有点类似于FirstOrDefault如果没有元素则返回一个默认值default(T),但是如果有多个元素则SingleOrDefault操作符还是会抛出异常

    例如:

     Person defaultTest = pers.Where(p => p.Sex=="").SingleOrDefault();

    结果:出现了这样的异常,因为查到的符合条件的信息有多个。

    Person defaultTest = pers.Where(p => p.Name="Olive").SingleOrDefault();

    结果:

    2.4ElementAtOrDefault:用于返回序列中指定位置的元素,如果指定索引的值不合法,则返回一个相关类型默认值元素

    示例:   Person defaultTest = pers.Where(p => p.Sex == "").ElementAtOrDefault(5);

    if (defaultTest != null)

                {

                    Console.WriteLine("ElementAtOrDefault查询结果:" + defaultTest.Name + "  " + defaultTest.Age + "   " + defaultTest.Sex);

                }

                else

                {

                    Console.WriteLine("ElementAtOrDefault查询结果:查无此人!");

                }

    结果:

    3Range,Repeat

    这两个方法均为System.Linq.Enumerable命名空间下Enumerable类的的静态方法,但不是扩展方法,具体使用如下:

    3.1Range:只能产生整数序列,且生成的为连续的序列

    Var rangeTest=Enumerable.Range(115,6);

    Foreach(var r in rangeTest)

    {

    Console.WriteLine("生成序列元素:"+r);

    }

    结果:

    3.2Repeat:可以产生重复的泛型序列

    Var var repeatTest = Enumerable.Repeat("Olive", 6);//函数参数:1、要重复的元素、2、重复产生的个数

                var rangeTest = Enumerable.Range(115, 6);

                foreach (var r in repeatTest)

                {

                    Console.WriteLine("Repeat生成序列元素:"+r);

                }

    结果:

    3、延迟执行

    延迟执行:查询变量本身只是存储查询命令,不保存查询结果,实际的查询执行会延迟到在 foreach 语句中循环访问查询变量时发生

        var serachtest = from p in pers

                                 where p.Sex == ""

                                 select p;

                foreach (var p in serachtest)

                {

                    Console.WriteLine("人员信息:" + p.Name + "  性别:" + p.Sex + "   年龄:" + p.Age);

                }

    结果:

    写到这里,可能大家还没有明白什么是执行?当然,在我的学的时候我也没有看明白。

    再看下面的例子

    int[] yanchishuzu = new int[] { 1, 2, 3,4, 5};

                var yuan = yanchishuzu.Select(y => y)

                foreach (int i in yuan)

                {

                    Console.WriteLine(i);

                }

                yanchishuzu[0] = 116;

                yanchishuzu[1] = 116;

                yanchishuzu[2] = 116;

                yanchishuzu[3] = 116;

                yanchishuzu[4] = 116;

                foreach (int i in yuan)

                {

                    Console.WriteLine(i);

                }

    结果:

    执行下面代码:

    int[] yanchishuzu = new int[] { 1, 2, 3,4, 5};

                var yuan = yanchishuzu.Select(y => y).ToList()

                foreach (int i in yuan)

                {

                    Console.WriteLine(i);

                }

                yanchishuzu[0] = 116;

                yanchishuzu[1] = 116;

                yanchishuzu[2] = 116;

                yanchishuzu[3] = 116;

                yanchishuzu[4] = 116;

                foreach (int i in yuan)

                {

                    Console.WriteLine(i);

                }

    结果:

    由两次实验结果可知:第一次两次执行后结果不一样,还得上边说过的吗?“查询变量本身只是存储查询命令,不保存查询结果”,在这里就得到了很好的体现,第一查询之后对数据源进行了更新,所以在第二次查询的时候,数据源已经发生了改变,所以查询的结果是不一样的,这种执行方式称为“延迟查询”,实际的查询执行会延迟到在 foreach 语句中循环访问查询变量时发生,所以当数据源发生变化是能马上做出反应。

    第二次实验两次的结果都一样,是因为在查询语句后边多了一个ToList()的方法,该方法是非延迟执行的,也就是马上执行,执行之后返回的是int[ ]集合来缓存对象,而不是IEnumerable<Int>集合对象,即使这个时候对数据源进行重置,但是Foreach执行循环的对象还是原来的对象,所以结果是不会改变的。

    经过这些讲解,你是不是对此有了新的体会呢?是不是有点明白了?下面将常用的LINQ查询的操作方法给列举了出来,从这个表里,你可以很清楚的明白哪些操作方法是延迟的,哪些是非延迟。这样就可以很好运用这一特性,实时的更新显示数据。

    Where

    过滤;延迟

    Select

    选择;延迟

    Distinct

    查询不重复的结果集;延迟

    Count

    返回集合中的元素个数,返回INT类型;不延迟

    LongCount

    返回集合中的元素个数,返回LONG类型;不延迟

    Sum

    返回集合中数值类型元素之和,集合应为INT类型集合;不延迟

    Min

    返回集合中元素的最小值;不延迟

    Max

    返回集合中元素的最大值;不延迟

    Average

    返回集合中的数值类型元素的平均值。集合应为数字类型集合,其返回值类型为double;不延迟

    Aggregate

    根据输入的表达式获取聚合值;不延迟

    4、非延时执行(ToList,ToArray,ToDictionary,SequenceEqual,First,Last,Single,Any,AllContains

    4.1ToList/ToArray

    ToList:用于将一个输入序列转换成一个类型为List<T>集合对象

    ToArray:生成并返回一个元素类型为T的数组

    这两个的作用差不多,上边在讲延迟执行的时候,已经举过例子,在这里就不再做示例了。

    4.2ToDictionary

    4.3FirstLastSingle

    First:从输出序列中选择第一元素输出

    Last:从输出序列中选择最后一个元素输出

    Single用于从输入序列中返回唯一的元素或满足条件的唯一元素,在这里需要特别注意,Single只能用于返回一个元素,如果返回序列有多个元素就会报错

    如图:

    这三个方法的使用都差不多,在这里只举一个First.

    示例: Person defaultTest = pers.Where(p => p.Sex == "").First();

    结果:

    4.3SequenceEqual:用于判断两个序列是否相等

     Bool  test=list.SequenceEqual(list1);

    如果两个序列相等则返回true,不相等则为false

    4.4AnyAll

    Any用于判断输入序列中所有元素是否都满足指定条件

    All判断输入序列中是否含有元素或者含有满足条件的元素

    这两方法的结果均为bool类型,通过判断可以所得序列的元素是否满足条件

    示例:

     bool anyTest = pers.All(p => p.Sex == "");

                if (anyTest)

                {

                    Console.WriteLine("ALL所有的人员不全是男性");

                }

                else

                    Console.WriteLine("ALL所有的人员都是男性");

    结果:

    Any的用法和All的用法差不多,这里就不做示例了。

    4.5Contains:判断序列中是否有指定的元素,返回布尔值

    示例:

    bool anyTest = pers.Select(p => p.Name).Contains("Olive");

                if (!anyTest)

                {

                    Console.WriteLine("Contains不存在所查询的元素!");

                }

                else

                    Console.WriteLine("Contains存在所查询的元素!");

    结果:

    这一节就讲到这里了,主要讲了延迟执行和非延迟执行,希望可以对大家有所帮助,也希望大家多多批评指正,共同探讨,共同进步。下一节我会主要讲LINQ TO XML

  • 相关阅读:
    牛客网 二叉树的镜像 JAVA
    牛客网 反转链表 JAVA
    牛客网 调整数组顺序使奇数位于偶数前面 JAVA
    Integer to Roman LeetCode Java
    Valid Number leetcode java
    Longest Common Prefix
    Wildcard Matching leetcode java
    Regular Expression Matching
    Longest Palindromic Substring
    Add Binary LeetCode Java
  • 原文地址:https://www.cnblogs.com/Olive116/p/2718105.html
Copyright © 2011-2022 走看看