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

  • 相关阅读:
    分析 ajax 请求并抓取 “今日头条的街拍图”
    requests + 正则表达式 获取 ‘猫眼电影top100’。
    爬虫基础(暂缓更新)
    Git 操作笔记:分布式版本控制系统
    python补充
    python基础
    8.最佳电影聚类分析
    文本分析 笔记
    7.文档聚类
    5.词项相似度分析
  • 原文地址:https://www.cnblogs.com/Olive116/p/2718105.html
Copyright © 2011-2022 走看看