(第一篇) 一步一步带你了解linq to Object
要想学好linq to object 我们必须要先学习lambda 表达式,学习lambda 表达式呢我们必须了解匿名函数和匿名类及扩展方法,学习匿名函数,我们必须学会委托,这是本文的宗旨。下面开始第一步。在第一步开始之前,我们做点准备工作,建立一个学生类和一个班级类,类结构如下
public class Student { public int Id { get; set; } public int ClassId { get; set; } public string Name { get; set; } public int Age { get; set; } public void Study() { Console.WriteLine("{0} {1}跟着Eleven老师学习.net高级开发", this.Id, this.Name); } } public class Class { public int Id { get; set; } public string ClassName { get; set; } }
在准备一个基础数据类
public class LinqShow { /// <summary> /// 准备数据 /// </summary> /// <returns></returns> public List<Student> GetStudentList() { #region 初始化数据 List<Student> studentList = new List<Student>() { new Student() { Id=1, Name="打兔子的猎人", ClassId=2, Age=35 }, new Student() { Id=1, Name="Alpha Go", 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="Nine", ClassId=2, Age=25 }, new Student() { Id=1, Name="Y", ClassId=2, Age=24 }, new Student() { Id=1, Name="小昶", ClassId=2, Age=21 }, new Student() { Id=1, Name="yoyo", ClassId=2, Age=22 }, new Student() { Id=1, Name="冰亮", ClassId=2, Age=34 }, 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=30 }, new Student() { Id=1, Name="小石头", ClassId=2, Age=28 }, new Student() { Id=1, Name="大海", ClassId=2, Age=30 }, new Student() { Id=3, Name="yoyo", ClassId=3, Age=30 }, new Student() { Id=4, Name="unknown", ClassId=4, Age=30 } }; #endregion return studentList; } }
简单了解委托
1. 委托是什么?
其实,我一直思考如何讲解委托,才能把委托说得更透彻。说实话,每个人都委托都有不同的见解,因为看问题的角度不同。个人认为,可以从以下2点来理解:
(1) 从数据结构来讲,委托是和类一样是一种用户自定义类型。
(2) 从设计模式来讲,委托(类)提供了方法(对象)的抽象。
既然委托是一种类型,那么它存储的是什么数据?
我们知道,委托是方法的抽象,它存储的就是一系列具有相同签名和返回回类型的方法的地址。调用委托的时候,委托包含的所有方法将被执行。
2. 委托类型的定义
委托是类型,就好像类是类型一样。与类一样,委托类型必须在被用来创建变量以及类型对象之前声明。
delegate void MyDel(int x);
委托类型声明:
(1) 以deleagate关键字开头。
(2)返回类型+委托类型名+参数列表。
3. 声明委托变量
MyDel del1,del2;
4. 初始化委托变量
(1) 使用new运算符
new运算符的操作数的组成如下:
- 委托类型名
- 一组圆括号,其中包含作为调用列表中的第一个成员的方法的名字。方法可以是实例方法或静态方法。
del1 = new MyDel( 实例方法名 ); del2 = new MyDel( 静态方法名 );
(2)使用快捷语法
快键语法,它仅由方法说明符构成。之所以能这样,是因为在方法名称和其相应的委托类型之间有隐式转换。
del1 = 实例方法名; del2 = 静态方法名;
5. 赋值委托
由于委托是引用类型,我们可以通过给它赋值来改变包含在委托变量中的方法地址引用。旧的引用会被垃圾回收器回收。
MyDel del; del = 实例方法名; //委托初始化 del = 静态方法名;//委托重新赋值,旧的引用将被回收
6. 委托调用
委托调用跟方法调用类似。委托调用后,调用列表的每个方法将会被执行。
在调用委托前,应判断委托是否为空。调用空委托会抛出异常,这是正常标准调用
if(null != del) { del.Invoke();//委托调用 }
在net 1.1的时代,我们是使用Invoke()方法类调用委托的。但是微软在net 2.0 的时候,我们可以这么去调用委托 直接 del();
if(null != del) { del();//委托调用 }
7. 综合练习
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Test { class Program { public delegate void meathed1();//1 委托的声明 委托是一种类型 public delegate int meathed2();//2 可以声明在类的内部,也可以声明在类的外部 public delegate void meathed3(int id, string name); public delegate string meathed4(string msg); static void Main(string[] args) { meathed1 me1 = new meathed1(m1); meathed2 me2 = new meathed2(m2); meathed3 me3 = new meathed3(m3); meathed4 me4 = new meathed4(m4); me1.Invoke(); int result= me2.Invoke(); Console.WriteLine(result); me3(1, "wbc"); Console.WriteLine(me4("您吃了吗")); Console.Read(); } public static void m1() { Console.WriteLine("我是无参数无返回值的方法"); } public static int m2() { Console.WriteLine("我是无参数有返回值的方法~~~~~~~~~"); return 123; } public static void m3(int id, string name) { Console.WriteLine($"我是有参数无返回值的方法,id={id},name={name}"); } public static string m4(string sparams) { Console.WriteLine($"我是无参数无返回值的方法 ,参数{sparams}"); return "参数返回了"; } } }
8. 多播委托
多播委托(MulticastDelegate)继承自 Delegate ,表示多路广播委托;即,其调用列表中可以拥有多个元素的委托。实际上,我们自定义的委托的基类就是 MulticastDelegate。这句话不好理解,继续往下看
List<Class> classList = new List<Class>() { new Class() { Id=1, ClassName="初级班" }, new Class() { Id=2, ClassName="高级班" }, new Class() { Id=3, ClassName="微信小程序" }, };View Code
表达式写法
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}"); }
在linq 中没有右链接,如果要写右链接,只能反过来写,这里不过多去写案列了,这种案列网上很多,一会总结过后,分享几篇
总结及推荐
1.匿名函数只能使用在委托中
2.var 关键字的特点,如何使用var 实现匿名类。
3. lambda 表达式
4.扩展方法
5.运算符linq 写法
6.表达式linq 写法
7 linq 的延迟加载原理
分享 1 linq 案列 ,很全面的
分享2 linq 标准查询操作符 很全面的 共五篇
- 在net中json序列化与反序列化 面向对象六大原则 (第一篇) 一步一步带你了解linq to Object 10分钟浅谈泛型协变与逆变
- Linq to Object 深入理解(一):了解Linq之前的基础知识
- 一步一步学Linq to sql(六):探究特性
- 【vs.net 2008系列-LINQ】 == to object 文章索引 ==
- IronPython and LINQ to Objects (IV): 实现IEnumerable<Object>
- LINQ系列:Linq to Object转换操作符
- 一步一步学Linq to sql(四):查询句法(非原创)
- 一步一步学Linq to sql(三):增删改
- LINQ系列:Linq to Object元素操作符
- 一步一步学Linq to sql(八):继承与关系
- 一步一步学Linq to sql(三):增删改
- 一步一步学linq to sql(一)
- 一步一步学Linq to sql(十):分层构架的例子
- 一步一步学Linq to sql(六):探究特性
- 一步一步学Linq to sql(一):预备知识
- 一步一步学Linq to sql(二):DataContext与实体
- 一步一步学Linq to sql(四):查询句法
- 一步一步学Linq to sql(六):探究特性
- C#示例学习(八)-Linq to object(5)分页效果
- Linq To Object查询问 4000 题