C# lambda 和 Linq


本章節給大家帶來的是Lambda 和 Linq 的關系

Lambda : 是實例化委托的一個參數,也就是一個方法

Linq:是基於委托(lambda)的封裝,代碼重用,邏輯解耦,是一個幫助類庫,linq是用泛型,委托,lamda實現的,總的來說:把對數據操作的通用部分完成,把可變的交給委托,使用者只關心可變部分。

一、Lambda

文章的開始已經說明Lambda是實例化委托的一個參數,也就是一個方法。那么我們通過代碼來體現一下:

{
    //.NetFramework 1.0-1.1的時候這樣應用
    NoReturnNoPara method = new NoReturnNoPara(DoNothing);
    method.Invoke();


    //.NetFramwork2.0 匿名方法出現,delegate關鍵字,可以訪問局部變量
    int i = 0;
    NoReturnWithPara method1 = new NoReturnWithPara(delegate (int id, int age)
    {
        Console.WriteLine(i);
        Console.WriteLine($"{id} 今年{age}歲了!");
    });
    method1.Invoke(1, 30);


    //.NetFramwork3.0 把delegate關鍵字去掉,然后增加了一個箭頭goes to
    //lambda表達式:參數列表=>方法體
    NoReturnWithPara method2 = new NoReturnWithPara((int id, int age) =>
    {
        Console.WriteLine(i);
        Console.WriteLine($"{id} 今年{age}歲了!");
    });
    method2.Invoke(1, 30);

    NoReturnWithPara method3 = new NoReturnWithPara((id, age) =>
    { //省略參數類型,但是編譯器可以根據委托推斷出類型,是語法糖
        Console.WriteLine(i);
        Console.WriteLine($"{id} 今年{age}歲了!");
    });
    method3.Invoke(1, 30);

    //如果方法體只有一行,可以去掉大括號和分號
    NoReturnWithPara method4 = new NoReturnWithPara((id, age) => Console.WriteLine($"{id} 今年{age}歲了!"));
    method4.Invoke(1, 30);

    //如果方法體只有一行,可以去掉大括號和分號,還可以去掉new NoReturnWithPara,這個也是編譯器語法糖
    NoReturnWithPara method5 = (id, age) => Console.WriteLine($"{id} 今年{age}歲了!");
    method4.Invoke(1, 30);

    //下面帶有返回值的
    Func<int> func0 = () => { return DateTime.Now.Month; };//有一個返回值
    Func<int> func1 = () => DateTime.Now.Month; //如果方法體只有一行,去掉大括號分號和return

}

使用反編譯工具看會產生一個私有sealed類,然后會看到lambda表達式都會生成一個方法名字,然后都會在包括在Sealed類里面

二、Linq

很多人會把Linq和lambda混淆,面試的時候問lambda是什么,很多同學反問不就是Linq嗎?

文章開頭也講述了Linq是基於委托(lambda)的封裝,代碼重用,邏輯解耦,是一個幫助類庫,linq是用泛型,委托,lamda實現的,總的來說:把對數據操作的通用部分完成,把可變的交給委托,使用者只關心可變部分。接下來舉個例子讓大家可以更好的認識Linq和使用Linq

首先初始化一些基礎數據:

private List<Student> GetStudentList()
{
    #region 初始化數據
    List<Student> studentList = new List<Student>()
            {
                new Student()
                {
                    Id=1,
                    Name="趙亮",
                    ClassId=2,
                    Age=35
                },
                new Student()
                {
                    Id=1,
                    Name="再努力一點",
                    ClassId=2,
                    Age=23
                },
                 new Student()
                {
                    Id=1,
                    Name="王炸",
                    ClassId=2,
                    Age=27
                },
                 new Student()
                {
                    Id=1,
                    Name="瘋子科學家",
                    ClassId=2,
                    Age=26
                },
                new Student()
                {
                    Id=1,
                    Name="",
                    ClassId=2,
                    Age=25
                },
                new Student()
                {
                    Id=1,
                    Name="黑騎士",
                    ClassId=2,
                    Age=24
                },
                new Student()
                {
                    Id=1,
                    Name="故鄉的風",
                    ClassId=2,
                    Age=21
                },
                 new Student()
                {
                    Id=1,
                    Name="晴天",
                    ClassId=2,
                    Age=22
                },
                 new Student()
                {
                    Id=1,
                    Name="旭光",
                    ClassId=2,
                    Age=34
                },
                 new Student()
                {
                    Id=1,
                    Name="oldkwok",
                    ClassId=2,
                    Age=30
                },
                new Student()
                {
                    Id=1,
                    Name="樂兒",
                    ClassId=2,
                    Age=30
                },
                new Student()
                {
                    Id=1,
                    Name="暴風輕語",
                    ClassId=2,
                    Age=30
                },
                new Student()
                {
                    Id=1,
                    Name="一個人的孤單",
                    ClassId=2,
                    Age=28
                },
                new Student()
                {
                    Id=1,
                    Name="小張",
                    ClassId=2,
                    Age=30
                },
                 new Student()
                {
                    Id=3,
                    Name="阿亮",
                    ClassId=3,
                    Age=30
                },
                  new Student()
                {
                    Id=4,
                    Name="37度",
                    ClassId=4,
                    Age=30
                }
                  ,
                  new Student()
                {
                    Id=4,
                    Name="關耳",
                    ClassId=4,
                    Age=30
                }
                  ,
                  new Student()
                {
                    Id=4,
                    Name="耳機俠",
                    ClassId=4,
                    Age=30
                },
                  new Student()
                {
                    Id=4,
                    Name="Wheat",
                    ClassId=4,
                    Age=30
                },
                  new Student()
                {
                    Id=4,
                    Name="Heaven",
                    ClassId=4,
                    Age=22
                },
                  new Student()
                {
                    Id=4,
                    Name="等待你的微笑",
                    ClassId=4,
                    Age=23
                },
                  new Student()
                {
                    Id=4,
                    Name="",
                    ClassId=4,
                    Age=25
                },
                  new Student()
                {
                    Id=4,
                    Name="混無痕",
                    ClassId=4,
                    Age=26
                },
                  new Student()
                {
                    Id=4,
                    Name="37度",
                    ClassId=4,
                    Age=28
                },
                  new Student()
                {
                    Id=4,
                    Name="新的世界",
                    ClassId=4,
                    Age=30
                },
                  new Student()
                {
                    Id=4,
                    Name="Rui",
                    ClassId=4,
                    Age=30
                },
                  new Student()
                {
                    Id=4,
                    Name="",
                    ClassId=4,
                    Age=30
                },
                  new Student()
                {
                    Id=4,
                    Name="肩膀",
                    ClassId=4,
                    Age=30
                },
                  new Student()
                {
                    Id=4,
                    Name="孤獨的根號三",
                    ClassId=4,
                    Age=30
                }
            };
    #endregion
    return studentList;
}
View Code

只要實現了IEnumerable這個接口,都是可以使用 where,Count等方法,只要底層是實現IEnumerable的,都是linq to object 

linq To object 是.netFramwork3.0的一個非常重大的改變

下面展示一下linq to object 的幾種使用方式

#region linq to object Show
{
    Console.WriteLine("********************");
    var list = from s in studentList
                where s.Age < 30
                select s;

    foreach (var item in list)
    {
        Console.WriteLine("Name={0}  Age={1}", item.Name, item.Age);
    }
}
          
{
    Console.WriteLine("********************");
    var list = studentList.Where<Student>(s => s.Age < 30)
                            .Select(s => new
                            {
                                IdName = s.Id + s.Name,
                                ClassName = s.ClassId == 2 ? "高級班" : "其他班"
                            });
    foreach (var item in list)
    {
        Console.WriteLine("Name={0}  Age={1}", item.ClassName, item.IdName);
    }
}
{
    Console.WriteLine("********************");
    var list = from s in studentList
                where s.Age < 30
                select new
                {
                    IdName = s.Id + s.Name,
                    ClassName = s.ClassId == 2 ? "高級班" : "其他班"
                };

    foreach (var item in list)
    {
        Console.WriteLine("Name={0}  Age={1}", item.ClassName, item.IdName);
    }
}
{
    Console.WriteLine("********************");
    var list = studentList.Where<Student>(s => s.Age < 30)//條件過濾
                            .Select(s => new//投影
                            {
                                Id = s.Id,
                                ClassId = s.ClassId,
                                IdName = s.Id + s.Name,
                                ClassName = s.ClassId == 2 ? "高級班" : "其他班"
                            })
                            .OrderBy(s => s.Id)//排序

                            .OrderByDescending(s => s.ClassId)//倒排
                            .Skip(2)//跳過幾條
                            .Take(3)//獲取幾條
                            ;
    foreach (var item in list)
    {
        Console.WriteLine($"Name={item.ClassName}  Age={item.IdName}");
    }
}
{//group by
    Console.WriteLine("********************");
    var list = from s in studentList
                where s.Age < 30
                group s by s.ClassId into sg
                select new
                {
                    key = sg.Key,
                    maxAge = sg.Max(t => t.Age)
                };
    foreach (var item in list)
    {
        Console.WriteLine($"key={item.key}  maxAge={item.maxAge}");
    }
    //group by new {s.ClassId,s.Age}
    //group by new {A=s.ClassId>1}
}
{
    Console.WriteLine("********************");
    var list = studentList.GroupBy(s => s.ClassId).Select(sg => new
    {
        key = sg.Key,
        maxAge = sg.Max(t => t.Age)
    });
    foreach (var item in list)
    {
        Console.WriteLine($"key={item.key}  maxAge={item.maxAge}");
    }
}
List<Class> classList = new List<Class>()
    {
        new Class()
        {
            Id=1,
            ClassName="初級班"
        },
        new Class()
        {
            Id=2,
            ClassName="高級班"
        },
        new Class()
        {
            Id=3,
            ClassName="微信小程序"
        },
    };
{
    var list = from s in studentList
                join c in classList on s.ClassId equals c.Id
                select new
                {
                    Name = s.Name,
                    CalssName = c.ClassName
                };
    foreach (var item in list)
    {
        Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
    }
}
{
    var list = studentList.Join(classList, s => s.ClassId, c => c.Id, (s, c) => new
    {
        Name = s.Name,
        CalssName = c.ClassName
    });
    foreach (var item in list)
    {
        Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
    }
}
{//左連接
    var list = from s in studentList
                join c in classList on s.ClassId equals c.Id
                into scList
                from sc in scList.DefaultIfEmpty()//
                select new
                {
                    Name = s.Name,
                    CalssName = sc == null ? "無班級" : sc.ClassName//c變sc,為空則用
                };
    foreach (var item in list)
    {
        Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
    }
    Console.WriteLine(list.Count());
}
{
    var list = studentList.Join(classList, s => s.ClassId, c => c.Id, (s, c) => new
    {
        Name = s.Name,
        CalssName = c.ClassName
    }).DefaultIfEmpty();//為空就沒有了
    foreach (var item in list)
    {
        Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
    }
    Console.WriteLine(list.Count());
}
#endregion

 linq to sql 運用的是表達式目錄樹,這個底層是實現的IQueryable,概念和linq to object是不一樣的!

參考文章:https://www.cnblogs.com/loverwangshan/p/10182516.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM