zoukankan      html  css  js  c++  java
  • Lambda(Linq)

    在谈到lambda表达式之前,首先要说一下委托,在下一章会详细介绍委托,在这里就是简单说明一下。

    委托的关键字段delegate,声明委托

            public delegate void NoReturnNoPara();//1 委托的声明
            public delegate int WithReturnNoPara();
            public delegate void NoReturnWithPara(int id, string name);
            public delegate LambdaShow WithReturnWithPara(DateTime time);    
    

    可以这样说吧,委托就好比于在C语言中的函数指针。

    在这里先声明一个无返回值的DoNothing方法

            private void DoNothing(int id, string name)
            {
                Console.WriteLine("{0} {1} DoNothing out",id,name);
            }    
    

    要使用委托必须方法签名相一致。

    在框架1.0时代。

                    NoReturnWithPara method = new NoReturnWithPara(this.DoNothing);//2 委托的实例化
                    method.Invoke(1, "ming");//3 委托的调用
                    method(2, "22");
    
     method.Invoke(1, "ming");和 method(2, "22");效果是一样的。
    后来随着版本的升级,又发生了一点变化,可以把new对象给省略。
                    NoReturnWithPara method = this.DoNothing;
                    method.Invoke(2, "jia");
    

     但是这样的写法,微软爸爸又觉得这样写不太方便,因为这样写需要提前准备个DoNothing方法,所以微软做了个大的修改,这回改的居然可以把DoNothing也省略,这就很方便了,没记错的话这应该是发生在框架3.0时代

                        NoReturnWithPara method = new NoReturnWithPara(
                        delegate(int id, string name)//把方法的声明改成了使用delegate关键字
                        {
                            
                            Console.WriteLine("{0} {1} DoNothing",id,name);
                        });
                    method.Invoke(3, "yy");
    

      这样写已经很便利了吧,但是“懒才是社会进步的动力”,为了偷懒,微软居然把delegate关键字也省略,改为=>(goes to)。

                   NoReturnWithPara method = new NoReturnWithPara(
                                     (int id, string name) =>//goes to
                                     //lambda表达式:是一个匿名方法,是一个方法
                                     {
                                         Console.WriteLine(nameOut);
                                         Console.WriteLine("{0} {1} DoNothing");
                                     });
                   method.Invoke(4, "N");
    

      已经到达这样了,但是人类还是不满足,后来索性把参数类型也省略,因为你要是这个委托,那肯定必须满足委托的参数类型

                    NoReturnWithPara method = new NoReturnWithPara(
                                         (id, name) =>
                                         //去掉参数类型,原因是委托的约束
                                         {
                                             Console.WriteLine("{0} {1} DoNothing",id,name);
                                         });
                    method.Invoke(5, "小小");
    

      都到这个地步了,我们还是可以偷偷懒的,只是需要满足几个条件。

    1)如果方法体只有一行,那么可以去掉大括号和分号,多行不行
    2)如果参数只有一个 可以去掉小括号
    3)如果没有参数,直接用小括号

                {
                  NoReturnWithPara method = new NoReturnWithPara((id, name) => Console.WriteLine("{0} {1} DoNothing", id, name));
                    method.Invoke(6, "分");
                 }        
    

    那么什么是 匿名类 和var关键字。

                      var model = new
                        {
                            Id = 1,
                            Name = " Go",
                            Age = 21,
                            ClassId = 2
                        };
                        Console.WriteLine(model.Id);
                        Console.WriteLine(model.Name);
    

    var:它主要用于在声明变量时,无法确定数据类型时使用

    就好比这个model,他的类型是不确定的,这就可以声明匿名类。

    再来讲讲系统自带委托Action/Func。

    Action是无返回值类型的委托,Func是带有返回值类型的委托。

                    Action act1 = () => Console.WriteLine("1234");
                    Action<int> act2 = t => { };
    
                    Func<int> func1 = () => 1;
                    int i = func1();
                    Func<int, string> func2 = t => "1234";
    

    什么是拓展方法呢。在这里我就不讲官方的语言了,就讲讲我的认识吧,其实拓展方法在我看来就是一些静态方法,在你调用这个方法时,不需要去创建一个对象,直接可以调用。

    那么怎么去创建一个拓展方法呢,其实很简单,主要是声明一个静态类,在静态类里面声明一个静态方法,方法的第一个参数声明一个对象,注意第一个参数类型前面加上this

            public static void NoShow(this LambdaShow show)
            {
                Console.WriteLine("这里是扩展的 NoShow");
            }
    
                        LambdaShow show = new LambdaShow();
                        show.Show();
                        show.NoShow();
    

    那万一类方法中有一个show方法,而拓展方法里面也有一个show方法,那通过show.Show();调用是调用类里面的方法还是拓展里面的方法呢?答案是类中的方法。

    接下来再来谈谈linq。在这里我就简单的说下linq几个常用的方法吧。

    创建一个student实体类

     public class Student
        {
      
            public int Id { get; set; }
            public int ClassId { get; set; }
            public string Name { get; set; }
            public int Age { get; set; }
        }
    

    初始化实体类,并添加一些数据。

     private List<Student> GetStudentList()
            {
               
                List<Student> studentList = new List<Student>()
                {
                    new Student()
                    {
                        Id=1,
                        Name="猎人",
                        ClassId=2,
                        Age=35
                    },
                    new Student()
                    {
                        Id=1,
                        Name=" Go",
                        ClassId=2,
                        Age=23
                    },
                     new Student()
                    {
                        Id=1,
                        Name="水",
                        ClassId=2,
                        Age=27
                    },
                     new Student()
                    {
                        Id=1,
                        Name="明",
                        ClassId=2,
                        Age=26
                    }
          }
    

    在这里提出一个需求,筛选出年龄大于25岁的同学。

    如果不适用linq只使用普通方法,大概是思路是先创建一个student的list对象,然后再把实体对象遍历判断条件,条件满足的添加到list集合中。

                List<Student> studentList = this.GetStudentList();
    
                List<Student> studentListlessThan25 = new List<Student>();
                foreach (var item in studentList)
                {
                    if (item.Age < 25)
                    {
                        studentListlessThan25.Add(item);
                    }
                }
    

    而如果我们使用Linq呢

                   var list = studentList.Where<Student>(s => s.Age < 25);
                    foreach (var item in list)
                    {
                        Console.WriteLine("Name={0}  Age={1}", item.Name, item.Age);
                    }
    

    如果你熟悉的话,这样看语句就跟看陈述句一样简单明了。

    那么我们不经要问,框架的where函数里面封装了哪些方法呢,让我们使用起来这么简单。通过反编译工具,其实里面的方法很简单

    模仿者框架中的where方法,试着自己写了一个方法。

     public static IEnumerable<TSource> XiMaWhere<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> func)
            {
                List<TSource> studentList = new List<TSource>();
                foreach (TSource item in source)
                {
                    bool bResult=func.Invoke(item);
                    if (bResult)
                    {
                        studentList.Add(item);
                    }
                }
                return studentList;
            }
    

    这就是where方法里面主要的一些内容

    然后我们可以跟where方法一样使用

                   var list = studentList.XiMaWhere<Student>(s => s.Age < 25);//陈述句
    
                    foreach (var item in list)
                    {
                        Console.WriteLine("Name={0}  Age={1}", item.Name, item.Age);
                    }
    

    是不是很强大!!!

    还有一些linq语句,这里就简单带过一下,有兴趣的可以自己去查阅资料

                   Console.WriteLine("********************");
                    var list = from s in studentList
                               where s.Age < 25
                               select s;
    
                    foreach (var item in list)
                    {
                        Console.WriteLine("Name={0}  Age={1}", item.Name, item.Age);
                    }
    

      

  • 相关阅读:
    uni-app开发经验分享六:页面跳转及提示框
    uni-app开发经验分享五: 解决三端页面兼容问题的方法
    LeetCode 535. TinyURL 的加密与解密
    LeetCode 807. 保持城市天际线
    LeetCode 84. 柱状图中最大的矩形
    LeetCode 198. 打家劫舍
    LeetCode 394. 字符串解码
    LeetCode 974. 和可被 K 整除的子数组
    LeetCode 142. 环形链表 II
    LeetCode 287. 寻找重复数
  • 原文地址:https://www.cnblogs.com/xima/p/7100932.html
Copyright © 2011-2022 走看看