program.cs
using System;
namespace LambdaAndLinq
{
class Program
{
static void Main(string[] args)
{
Lambda.Show_();
//Lambda是什么? 是实例化委托时传入的参数,是一个匿名方法
//但是编译时会产生一个私有sealed类,给方法分配一个名字,放入这个给类中
Console.WriteLine("Hello World!");
C c = new C();
c.Name = "";
Linq.call();
Linq.call_0();
}
}
public class A
{
public virtual string Name { set; get; }
public virtual void DoNothing()
{
Console.WriteLine("A DoNothing");
}
}
public class B : A
{
public sealed override string Name { set; get; }
public sealed override void DoNothing()
{
base.DoNothing();
}
}
public class C : B
{
//因为B中密封,所以不能重写
//public override string Name { set; get; }
}
}
Lambda.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace LambdaAndLinq
{
//委托可以定义在类外面
public delegate void NoReturnNoPara_();
public delegate void NoReturnIntPara_(int i);
public class Lambda
{
#region Lambda发展历史
public delegate void NoReturnNoPara();
public delegate void NoReturnIntPara(int i);
//Lambda是什么? 是实例化委托时传入的参数,是一个匿名方法
//但是编译时会产生一个私有sealed类,给方法分配一个名字,放入这个给类中
//sealed关键字复习:1,修饰类时,任何类不能继承被修饰的类。2,修饰属性方法时,继承父类虚方法或虚属性后,防止被子类重写
//多播委托中如果直接传入Lambda,虽然方法体一样,但是时不同的的方法
public void Show()
{
//Lambda演变史
{
//.NetFramework 1.0
NoReturnNoPara NoReturnIntPara = new NoReturnNoPara(DoNothing);
NoReturnIntPara.Invoke();
NoReturnIntPara noReturnNoPara = new NoReturnIntPara(DoWithPara);
noReturnNoPara.Invoke(123);
}
{
//.NetFramework 2.0 方法名换成delegate关键字-->匿名方法
NoReturnNoPara NoReturnIntPara = new NoReturnNoPara(delegate { Console.WriteLine("This is DoNothing"); });
//相比1.0,可以给方法体中传入额外的变量,比如这个j
int j = 9;
NoReturnIntPara noReturnNoPara = new NoReturnIntPara(delegate (int i) { Console.WriteLine($"i is {i},j is {j}"); });
}
{
//.NetFramework 3.0 delegate 关键字省略,增加=> goes to
//lambda表达式
NoReturnIntPara noReturnNoPara = new NoReturnIntPara((int i) => { Console.WriteLine($"i is {i}"); });
}
{
//参数类型省略
//方法体如果只有一句话,方法大括号和结尾分号也可以省略
//委托 new可以省略
NoReturnIntPara noReturnNoPara = (int i) => Console.WriteLine($"i is {i}");
//带返回值的委托,只有一行可以省略return关键字
Func<int> func = () => 2;
}
}
private void DoNothing()
{
Console.WriteLine("This is DoNothing");
}
private void DoWithPara(int i)
{
Console.WriteLine($"i is {i}");
}
#endregion
#region 3.0出现匿名类 匿名类中的属性是只读的
public static void Show_()
{
//3.0 object定义的匿名类,无法访问其中的元素
object student = new { age = 10, Name = "小高" };
//4.0 dynamic 动态类型,避开编译器检查,但不安全
dynamic student0 = new { age = 10, Name = "小高" };
//student0.age = 10; //虽然可以写,但运行时报错,因为age只读
//var 语法糖 它定义的类中属性时只读的
var student1 = new
{
age = 10,
Name = "小高",
};
//student1.age = 10; //不能写,报错,因为age只读
}
#endregion
#region 3.0出现扩展方法
//扩展方法必须定义在非泛型静态类中,也不能定义在嵌套类中
//扩展方法,像实例方法一样使用
//用处1,第三方类,不适合修改源码(但是实例方法有可能和扩展方法同名,此时以实例方法为准)
//用处2,适合组件式开发的扩展(core中);定义接口或者类,是按照最小需求,但是在开发中又经常需要一些方法,就定义成扩展方法,比如context.Response.WriteAsync、中间件注册等
//注意:不要为object和没有约束的泛型定义扩展,会造成污染
public void Show1()
{
AA a = new AA();
a.Show();
a.ExtendShow();
}
#endregion
}
public class AA
{
public void Show()
{
Console.WriteLine("AA_Show");
}
}
//扩展方法必须定义在非泛型静态类中,也不能定义在嵌套类中
public static class ExtendAA
{
public static void ExtendShow(this AA aA)
{
Console.WriteLine("ExtendAA_Show");
}
}
}
Linq.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LambdaAndLinq
{
public class Linq
{
#region 迭代器模式
//扩展方法的好处,陈述式语法
//迭代器模式 Iterator
//lambda用来实例化委托,是个方法
//linq是个类库,依靠泛型,lambda,委托等实现
public static void call()
{
var rst = new List<Student>();
rst.Add(new Student { Name = "大王", Age = 19 });
rst.Add(new Student { Name = "小高", Age = 16 });
rst.Add(new Student { Name = "小王", Age = 17 });
rst.Add(new Student { Name = "小高1", Age = 18 });
rst.Add(new Student { Name = "小高2", Age = 18 });
{
var sss = rst.WhereNew(s => s.Name == "小王" || s.Age >= 18);
foreach (var item in sss)
{
Console.WriteLine(item.Name);
}
}
{
//迭代器模式,循环sss时才进入WhereNewIterator方法,并且找到满足的第一个就返回,下次进来接着上次迭代循环的地方继续,延迟加载
//如果.ToList了,那么迭代器会一次执行完
var sss = rst.WhereNewIterator(s => s.Name == "小王" || s.Age >= 18);
var sss0 = rst.WhereNewIterator(s => s.Name == "小王" || s.Age >= 18).ToList();
foreach (var item in sss)
{
Console.WriteLine(item.Name);
}
}
}
#endregion
#region Linq to Object 和 Linq to SQL
public static void call_0()
{
#region Linq to Object 在Enumerable类,针对IEnumerable数据,指的是内存数据
//linq:把对数据的通用操作完成,可变的逻辑交给委托 的这么一种封装
//where:把对数据的通用操作完成,可变的过滤逻辑交给委托
//select:把对数据的通用操作完成,可变的转换筛选逻辑交给委托
List<Student> students = new List<Student>();
students.Add(new Student { Name = "大王", Age = 19, Id = 1 });
students.Add(new Student { Name = "小高", Age = 16, Id = 3 });
students.Add(new Student { Name = "小王", Age = 17, Id = 5 });
students.Add(new Student { Name = "小高1", Age = 18, Id = 4 });
students.Add(new Student { Name = "小高2", Age = 18, Id = 6 });
var rst = students.Where(item => item.Age >= 16)
.Select(stu => new
{
name = stu.Name,
age = stu.Age,
id = stu.Id
}).OrderBy(stu => stu.age)
//.OrderBy(t=>t.id)
.ThenBy(t => t.id)
.Skip(2)
.Take(3)
.ToList();
var rst1 = students.GroupBy(t => t.Age).Select(ts => new
{
age = ts.Key,
name = string.Join(',', ts.Select(t => t.Name)),
id = ts.Select(t => t.Id).Sum()
});
#endregion
#region Linq to SQL 在Queryable类,针对IQueryable数据,操作数据库
//程序操作数据库,需要Ado.net+Sql
//封装了通用数据库操作,可变的是SQL,SQL通过表达目录树来传递,这个是可以解析的
var Questudents = students.AsQueryable();
var rst2 = Questudents.Where(t => t.Age > 17);
{
//Linq to Object 传入委托,可以写任意方法体
//Linq to SQL 传入的是需要解析成SQL的表达是目录树,虽然写法和Linq to Object 类似,但是需要受限制
var rst3 = students.Where(t =>
{
Console.WriteLine("-------");
return t.Age > 17;
});
//需要传入的表达式目录树能解析成SQL,所以不能这么写
//var rst4 = Questudents.Where(t =>
//{
// Console.WriteLine("-------");
// return t.Age > 17;
//});
}
#endregion
#region Linq to XML
#endregion
}
#endregion
}
public class Student
{
public string Name { set; get; }
public int Age { set; get; }
public int Id { set; get; }
}
//以linq的方式给List类型加上自定义扩展方法
public static class LinqMyExtend
{
public static List<T> WhereNew<T>(this List<T> students, Func<T, bool> func)
{
var rst = new List<T>();
foreach (var item in students)
{
Console.WriteLine("正在检查");
if (func.Invoke(item))
rst.Add(item);
}
return rst;
}
//迭代器模式,延迟加载
public static IEnumerable<T> WhereNewIterator<T>(this List<T> students, Func<T, bool> func)
{
var rst = new List<T>();
foreach (var item in students)
{
Console.WriteLine("正在检查");
if (func.Invoke(item))
yield return item; //yield配合IEnumerable使用
}
}
}
}