1、Lambda表达式
** 左边参数列表,右边方法体,中间goes to。本质是个方法。**
1 | public delegate void NoReturnNoPara(); |
1 | //可以省略 编译器推算的 |
1 | NoReturnWithPara method = (x, y) => Console.WriteLine("This is DoNothing6"); //实例化委托 // 极简模式,一句话的话,Lambda表达式的大括号和分号,可以省略掉。传入的参数类型也可以省略。 |
2、Lambda表达式本质是什么?
**
**
** **使用ILSpy反编译工具查看本质。 ( Lambda表达式是一个类种类里面的一个internal方法,然后被绑定到静态的委托类型的字段。)
委托的本质是个类。
** 多播委托+匿名方法**01:
1 | NoReturnWithPara method02 = new NoReturnWithPara(delegate(int i, int i1) {Console.WriteLine("This is DoNothing1");}); |
** 多播委托+**Lambda表达式02:
1 | { |
另外:发布(注册)+订阅机制详细了解!需要后面详细了解!
**
**
**
Lambda表达式的应用场景:
**
1、委托实例化的时候应用。
1 | public int Id=>3; // c#7.0 属性可以使用Lambda! |
3、s=>s>10; s为Lambda表达式方法的参数,s>10为Lambda表达式方法的方法体。
**
3、匿名类
** **匿名类只能get,不能set。
1 | var model = new { //Object 编译器不通过,使用 var/dynamic 可以通过。另外通过反射也可以访问。 编译后有一个真实的类。 |
1 | dynamic dModel = new{ |
var(弱类型、智能推断,语法糖)、dynamic(动态编译,避开编译器的复杂类型)、Object(具体类,所有的基类)
但是var 必须在声明的时候就确定类型,确定类型后不能修改。(不同于弱语言)
4、扩展方法
.net3.0以后出现。
01、扩展方法的用途:
** **扩展方法能够向现有类型添加方法。而无需创建新的派生类型、重新编译或以其他方式修改原始类型。
三个层面:.Net内置对象的扩展方法、一般对象的拓展方法、泛型对象的扩展方法。
02、拓展方法的使用要求条件:
01、同一命名空间下使用。
02、静态类的静态方法调用(需要传入普通实例)的简化。但是声明的时候要加上 “this”。
** ** 03、简化成直接用“需要传入普通实例”直接调用静态方法。(直接省略掉了静态类的调用)
03、使用扩展方法的缺陷:
这个方法同时存在的情况下,普通类型中定义了,静态类中的静态方法也定义了(使用this,成为了扩展方法)
编辑器优先调用的是普通类型定义的方法。(原先类型中发现问题,添加上了扩展方法的内容,使用饿是普通类型的定义方法),作为扩展方法来说,是一个隐患。
尽量不要扩展基类型,可能会导致被覆盖,导致所有子类都能被调用到。成本太高!
扩展方法的使用最好针对指定类型扩展。
04、?、??、?:、?. 的使用小知识:
?表示可空类型。 int? a=null a为可空的int类型。 在数据库中经常用到,定义的类型值可空。
??表示空合并运算符。a??b 当a为null时返回b,a不为null时则返回a本身。
?: 表示三元运算符。 x?y:z 表示表达式x为true时,则返回y;如果表达式x为false时,则返回z。这是if(x){y}/else{z}的简写形式。
?. 表示不为null的情况下,往下进行。如果对象是nul,直接返回null。
1 | public static int ToInt(this int? iValue) |
使用案例01:
1 | public static int ToInt(this int? iValue, int defaultValue = 0) |
1 | int?iValue = null; |
使用案例02:
1 | public static int ToGetLenth(this object oValue) //此时调用类型是object,所有子类都会由此方法。尽量不要扩展object |
05、扩展方法使用泛型
1 | public static void Show2<T>(this T t) //最好加约束 |
Linq 语言集成查询
1. 数据过滤。陈述式语法。Linq扩展方法(静态类下的静态方法)。Linq泛型委托。
** 2. 支持非泛型IEnumerable接口类型(如ArrayList)。**IEnumerable<T>
** 3. 延迟执行/立即执行。——这个重点再探索!!!**查询的执行与查询不同
Linq的概念:
LINQ: Language Integrated Query 语言集成查询,其本质是对ADO.NET结果集 通过反射联通泛型特性转换成对象集,实现OR模型饿转换(类似于Java中的Hibernate框架,.Net中俄NHibernate),它完全是基于.NET2.0的框架。
LINQ是一组语言特性和API,使得你可以使用统一的方式编写各种查询。用于保存和检索来自不同数据源的数据,从而消除了编程语言与数据库之间的不匹配,以及为不同类型的数据源提供单个查询接口。
LINQ总是使用对象,因此可以使用相同的查询语法来查询和转换xml、对象集合、SQL数据库、ADO.NET数据机以及任何其他可用的LINQ提供程序格式的数据。
Linq的优缺点:
** **优点:在于封装了SQL语句,只对对象进行操作(增删改查),代码量大大减少让我们重点关心业务逻辑,而非代码上,把我们引入面向对象的编程方式上来;
缺点:追求效益的同时牺牲了性能,比起ADO.Net性能稍差(ADO.Net更有优势,不需要进行OR转换),另外对一些复杂的SQL语句不好操作,虽然也支持(联合、分组、排序、连接查询等)
所以要选择性的使用。
LINQ主要包括:
** **解决了可以在编译期间进行检查。
1、Linq To Objects 主要负责对象的查询。 特点是操作内存中的数据。
2、Linq To XML 主要负责XML的查询。 特点是操作xml中的数据。 通用的东西封装起来,linq的方式读写改等访问。
3、Linq To ADO.NET 主要负责数据库的查询。
** Linq To Sql ** 特点是操作数据库中的数据。
Linq To DataSet
Linq To Entities
4、Linq To Excel 还没有封装
Linq To NoSql 还没有封装,放在内存中的数据库 ,如:Redis(有五种数据结构)
设计思想:
Linq To Everything。 面向对象语言的革新。 数据结构+算法!
Linq 对数据源的操作封装。不用关注来源,不关注底层。框架封装的最高境界!
** ————————另外注意:SQL中的01视图(View)、02事务(Transaction)、03存储过程、04索引、05约束、06触发器、07事件!还需深入的地方!!!————————**
1 | var list=intList.Where<int>(t=>t<80); //扩展方法Where,框架自带的泛型的扩展方法。 //泛型+迭代器提供特性。 //陈述式语法. |
1 | public static List<int> myWhere(List<int> intList,Func<int,bool> func) |
1 | Func<int,bool>func =i=>i>100; //predicate<int> |
1 | public static List<int> myWhere(this List<int> intList,Func<int,bool> func) //这个静态方法要放在静态类中 |
1 | Func<int,bool>func02 =i=>i>100; //predicate<int>更专业的使用? |
1 | var list03=intList.myWhere(i=>i>100); //最终可以简写成为的形式。 Linq的扩展方法! |
1 | public static List<T> myWhere(this List<T> intList,Func<T,bool> func) // 泛型后可满足各种类型 各种条件的筛选 |
Linq的思想本质:
泛型委托传递的经典使用。****
1、基于委托封装解耦,去掉重复代码,完成通用代码。
2、泛型,应对各种数据类型。
3、加迭代器,延迟获取,按需获取。List本身是实现了IEnumerable<T>的接口。
** **Linq的使用本质原理:
对数据集合的操作(将一个集合转成另外一个集合),最大值Max、最小值Min、Sum和、 Select投影转换、Where筛选过滤、OrderBy生序/降序等封装 … …
使用泛型和迭代器提供特性。
IEnumerbale、IEnumerable<T>
** **Linq to objects ,新的处理集合的方法。只需编写描述要检索的内容饿声明性代码。
可以使用Linq来查询任何可枚举的集合。(可以是Dictionary)
1 | public static IEnumerabel<T> myWhere(this List<T> intList,Func<T,bool> func) // 泛型后可满足各种类型 各种条件的筛选 |
**迭代器的使用 **
** **yield 延迟查询,真正使用使用才调用。
详细了解… …?
数据结构… …?
IQueryable? (Linq to sql) 可查询。 对数据库数据的过滤。 Where封装了通用代码。 封装的代码是SQL+ADO.NET的,传的是“表达式目录树”解析SQL, 表达式目录树不同于委托。 对不同的表都可以进行过滤。
IEnumerbale?(Linq to objects) 可枚举。 对内存中数据的过滤。 Where基于泛型的委托封装的拓展方法。
Expression表达式目录树?
LINQ查询表达式:
** 关键字
**
** **From 获取数据源
Where 筛选(条件过滤)以布尔表达式的形式
OrderBy 中间件排序 升序/降序等
Group by 结果以列表的形式列出 Group by… into… // into作为进一步查询标识符
** Join 联结. 两张表关联查询。 On 表达式 “外键”**
Select 投影 生成除源元素副本以外的内容,该操作称之为投影
Linq 查询三部曲:
1.获取数据源 2.创建查询 3.执行查询
使用Linq进行数据转换(Linq查询最强大的功能是能够创建新类型)
写法一:
1 | var list=studentList.Where<Student>(s=>s.Age<30) |
1 | foreach(var item in list) |
写法二:
1 | var list=from s in studentList //边查询边投影 |
另外:将多个输入连接到一个输出序列Concat
拓展一:Orderby的使用
1 | var list = studentList.Where<Student>(s => s.Age < 30)//条件过滤 |
1 | foreach (var item in list) |
拓展二:Group By的使用 **** ——****单表联查——
写法一:
1 | var list = from s in studentList |
1 | foreach (var item in list) |
写法二:
1 | var list = studentList.GroupBy(s => s.ClassId) |
1 | foreach (var item in list) |
拓展三:Join的使用(内连接、左连接、右连接****) ——多表联查——
内连接写法一:
1 | var list = from s in studentList |
1 | foreach (var item in list) |
内连接写法二:
1 | var list = studentList.Join(classList, s => s.ClassId, c => c.Id, (s, c) => new |
1 | foreach (var item in list) |
左连接写法一:
1 | var list = from s in studentList |
1 | foreach (var item in list) |
左连接写法二:
1 | var list = studentList.Join(classList, s => s.ClassId, c => c.Id, (s, c) => new |
1 | foreach (var item in list) |
Linq中sql复杂查询比较麻烦。
LINQ查询表达式与SQL查询表达式的区别?
????
**
**
** Linq查询文档的继续学习?**
https://www.cnblogs.com/liqingwen/p/5832322.html
https://www.cnblogs.com/liqingwen/p/5801249.html****
延伸冒泡排序:
双for循环,二叉树排序… ….
- 本文作者: 梁俊可
- 本文链接: http://ljk3d.com/2021/10/19/cSharpNote/CSharp高级进阶教程_06_Lambda表达式02、匿名类、扩展方法、Linq语言集成查询/
- 版权声明: 梁俊可工作室