C#学习笔记(Linq)20240802
创始人
2024-11-14 16:33:58
0

文章目录

    • 委托
    • lambda表达式
    • 揭秘linq方法的背后
    • Linq常用的扩展方法

委托

  1. 委托是可以指向方法的类型,调用委托变量时执行的就是变量指向的方法
  2. .net中定义了泛型委托Action(无返回值)和Func(有返回值),所以一般不用自定义委托类型。委托变量不仅可以指向普通方法,还可以指向匿名方法:
            Func f1 = delegate (int i1, int i2)             {                 return $"{i1}+{i2}={i1 + i2}";             };              string s = f1(1, 2); 

lambda表达式

匿名方法可以写成lambda表达式

 Func f1 = (i1, i2) =>  //可以省略参数数据类型,因为编译器根据委托类型推断出参数类型用=>引出来方法体             {                 return $"{i1}+{i2}={i1 + i2}";             }; 

如果委托没有返回值,且方法体只有一行代码,只省略{ }

Action a1 = (age, name) => Console.WriteLine($"年龄{age},姓名{name}");             a1(18, "zzh"); 

如果=>之后的方法体中只有一行代码,且方法有返回值,那么可以省略方法体的{ }以及return

Func f1 = (i1, i2) => $"{i1}+{i2}={i1 + i2}"; 

如果只有一个参数,参数的()可以省略

Action f1 = s => Console.WriteLine(s);             Func f2 = i => i > 5; 

揭秘linq方法的背后

linq中提供了很多集合的扩展方法,配合lambda能简化数据处理

int[] nums = new int[]                 {3,99,88,77,7,8,9,66,15,7 };             IEnumerable items = nums.Where(i => i > 10); 

可以使用var让编译器的“类型推断”来简化类型的声明,在linq中常用。C#的var和JavaScript的var不一样,仍然是强类型的,C#中的弱类型的dynamic

Where可以自行定义

static IEnumerable MyWhere1(IEnumerable items, Func f)         {             List result = new List();              foreach(int i in items)             {                 if (f(i) == true)                 {                     result.Add(i);                 }             }             return result;         } 

Linq常用的扩展方法

linq中提供了大量类似where的扩展方法,简化数据处理。大部分都在System.Linq命名空间中

where方法:每一项数据都会经过predicate的测试,如果针对一个元素,predicate执行的返回值为true,那么这个元素就会放到返回值中。where参数是一个lambda表达式格式的匿名方法,方法的参数e表示当前判断的元素对象。参数的名字不一定非要叫e,不过一般lambda表达式中的变量名长度都不长

1、Count()方法:用于统计,返回int类型的数字,会全部遍历

int count1 = list.Count(e => e.Salary > 5000 || e.Age < 30); int count2 = list.Where(e => e.Salary > 5000 || e.Age < 30).Count(); 

2、Any()方法:查询是否至少有一条符合,返回bool类型,不会全部遍历,有符合就直接返回

bool b1 = list.Any(e => e.Salary > 8000); bool b2 = list.Where(e => e.Salary > 8000).Any(); 

有可能比Count()实现效率高

3、Single有且只有一条满足要求的数据,若有多条数据符合直接报错。
报错信息为:System.InvalidOperationException:“Sequence contains more than one element”

Employee e1 = list.Where(e => e.Name.Equals("Jerry")).Single();             Employee e2 = List.Single(e => e.Name.Equals("Jerry")); 

4、SingleOrDefault 最多只有一条满足要求的数据,没有就返回默认值null

Employee e2 = list.SingleOrDefault(e => e.Name.Equals("Jerry")); 

5、First至少有一条,返回第一条,若没有一条符合则报错
报错信息为:System.InvalidOperationException:“Sequence contains no matching element”

Employee e3 = list.First(e => e.Age > 30); 

6、FirstOrFault 返回第一条或默认值

Employee e4 = List.First(e => e.Age > 30); 

7、OrderBy排序 | ThenBy然后排序

IEnumerable el1 = list.OrderBy(e => e.Name[0]).ThenBy(e => e.Age); 

8、OrderByDescending倒叙排序 | ThenByDescending 然后倒叙排序

IEnumerable el2 = list.OrderByDescending(e => e.Name[0]).ThenByDescending(e => e.Age);  

若后者写成OrderByDescending会以最后一个进行排序

9、Skip跳过部分数据 | Take取部分数据

IEnumerable el3 = list.Skip(3).Take(2);  

Skip()、Task()也可以单独使用

10、Max最大值 | Min最小值 | Average平均值 | Sum求和 | Count 统计

int max =list.Max(e=>e.Age); 

11、GroupBy 分组

IEnumerable> items=list.GroupBy(e=>e.Age); 

12、Select 投影

var items1 = list.Select(e => new {Name = e.Name, Age = e.Age}); IEnumerable items2 = list.Select(e => new Employee {Name = e.Name, Age = e.Age});  

把集合中的每一项转换为另外一种类型

IEnumerable ages = list.Select(e => e.Age); IEnumerable names = list.Select(e=>e.Gender?"男":"女"); var dogs = list.Select(p=>new Dog{NickName=e.Name,Age=e.Age}); 

匿名类型:

var p = new {Name="tom",Id=1}; var p1 = new {name,Id=1,p.Age}; 

投影与匿名类型:

var items = list.Select(e=>new {e.Name,e.Age,XingBie= e.Gender ? "男" : "女"}); var items = list.GroupBy(e => e.Gender).Select(g=>new { Gender=g.Key,Count=g.Count(),AvgSalary= g.Average(e => e.Salary),MinAge= g.Min(e => e.Age)}); 

13、链式调用

集合转换:有一些地方需要数组类型或者List类型的变量,我们可以用ToArray()方法和ToList()分别把IEnumerable转换为数组类型和List类型

IEnumerable items = list.Where(it => it.Salary > 3000);  List listE = items.ToList(); Employee[] arrayE = items.ToArray();  

链式调用:Where、Select、OrderBy、GroupBy、Task、Skip等返回值都是IEnumerable类型,所以可以链式调用。例如:“获取Id>2的数据,然后按照Age分组,并且把分组按照Age排序,然后取出前3条,最后再投影取得年龄、人数、平均工资”

var items = list.Where(it => it.Id > 2).GroupBy(it=>it.Age).OrderBy(it=>it.Key).Take(3).Select(it=>new {Nianling = it.Key,RenShu=it.Count(),AvgS=it.Average(g=>g.Salary) });  foreach (var item in items) {       Console.WriteLine($"Nianling={item.Nianling},RenShu={item.RenShu},AvgS={item.AvgS}"); }  

14、Linq另一种倩影

var items2 = from e in list             where e.Salary > 3000             orderby e.Age             select new { e.Name, e.Age, Gender = e.Gender ? "男" : "女" }; 

相关内容

热门资讯

绝活儿透视挂!中至余干可以装挂... 绝活儿透视挂!中至余干可以装挂(辅助)其实真的是有辅助脚本(哔哩哔哩)1)中至余干可以装挂辅助插件:...
两分钟外挂透视!we-poke... 两分钟外挂透视!we-poker软件,wepoker私人定制透视(真实有挂)-哔哩哔哩暗藏猫腻,小编...
秘籍透视挂!菠萝辅助器1.3(... 秘籍透视挂!菠萝辅助器1.3(辅助)总是是真的有辅助工具(哔哩哔哩)1、菠萝辅助器1.3辅助软件下载...
9分钟外挂透视!wepoker... 9分钟外挂透视!wepoker怎么拿到好牌,德扑之心免费透视(真是有挂)-哔哩哔哩1、上手简单,内置...
经验透视挂!点星休闲辅助器下载... 经验透视挂!点星休闲辅助器下载(辅助)一直真的是有辅助攻略(哔哩哔哩)1、打开软件启动之后找到中间准...
第八分钟外挂透视!wpk俱乐部... 第八分钟外挂透视!wpk俱乐部怎么透视挂,aapoker插件(了解有挂)-哔哩哔哩wpk俱乐部怎么透...
学习透视挂!哈糖大菠萝提高胜率... 学习透视挂!哈糖大菠萝提高胜率(辅助)原来一直总是有辅助工具(哔哩哔哩)哈糖大菠萝提高胜率是不是有人...
9分钟外挂透视!wepoker... 9分钟外挂透视!wepoker智能辅助插件,wepoker智能辅助插件(有人有挂)-哔哩哔哩在进入w...
第4分钟外挂透视!德普之星透视... 第4分钟外挂透视!德普之星透视辅助软件激活码,wepoker到底有没有透视(有挂神器)-哔哩哔哩1、...
妙计透视挂!禅游指尖四川修改器... 妙计透视挂!禅游指尖四川修改器(辅助)原来是真的有辅助技巧(哔哩哔哩)1、许多玩家不知道禅游指尖四川...