需要明确一点,委托本质是类,通过ILSPY查看定义的委托即知,继承自一个多播委托类,
MulticastDelegate,声明一个委托,和定义一个类是一样的,因此它可以new MyDelegate(),以及调用各种方法
lambda本质是啥呢?就是方法,它既不是委托,也不是委托的实例,
通过ILSPY可查看,编译器通过一个内部类,将lambda表达式,编译为自定义的方法后,再绑定到委托,
涉及知识点:
第一:委托几种初始化方法
第二:委托里的lambda本质是方法
第三:C#自带两组委托,一个带返回值,一个不带返回值
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace delegate关键字
{
class Program
{
public delegate void Del();
static void Main(string[] args)
{
//第一个知识点:初始化委托方法
int k = 10;
//常规,原始方法定义委托,先定义一个方法,里面无法访问k,局部变量
Del del1 = new Del(Test);
//第二种方法:利用delegate关键字
Del del2 = delegate() {
Console.WriteLine(k);
};
//第三种方式,lamda
Del del3 = () => {
Console.WriteLine("我是lambda表达式,省掉new,实际上语法糖,编译器编译的时候,自动补上new");
};
//思考一下lambda表达式,到底是什么?
//本质就是一个方法,基于语法糖它省掉方法诸多形式,
// 它看起来像是委托,但它不是,因为委托是一个类,一种类型,看起来右边lambda可以给委托赋值,
//右边lambda看起来像是委托的一个实例,但是它也不是委托的实例,因为这里是编译器提供的语法糖,
//准确地说,lambda是实例化一个实例化委托所需要的参数,即方法
//额外补充一点,语法糖,看起来写起来更方便,另外一个方面,让人产生疑惑,
//勘破迷雾的本质,一双火眼金睛,利器就是反编译+IL
//本质lambda后台,编译器通过生成一个密封的自动类,里面自动生成一些自定义的临时方法,
//赋值给委托,相当于new出来委托
//第二个知识点,lambda本质,
del3+=()=>{
Console.WriteLine("1");
};
del3 += () =>
{
Console.WriteLine("1");
};
del3 += () =>
{
Console.WriteLine("1");
};
//del3 -= () =>
//{
// Console.WriteLine("1");
//};
//del3 -= () =>
//{
// Console.WriteLine("1");
//};
del3.Invoke();//输出三个1
//Console.WriteLine();
//lambda写起来很爽,但是注册多播委托后,无法移除,因为本质上,就是形成多个独一无二的方法,
//无法找到当初那个委托,尽管写的lambda一模一样
//C#内置两组委托,3.0框架内置
//第三个知识点:C#内置的一组委托,带返回值,不带返回值,够用
Action action0 = () => { };
//这里一个参数,可以省略()
//泛型方法里面,就是()中的参数类型列表
Action<string> action1 = g => { };
Action<int,string> action2 = (i,g) => { };
Action<int, string, DateTime, char, int, string, DateTime, char, int, string, DateTime, char, int, string, DateTime, char> action16 = null;
//那么
Func<int> fun0 = () =>
{
return DateTime.Now.Year;
};
//只有一行,可以去掉大括号,分号,return如何Actio区分?
//取决于左边,
Func<int, string> func1 = (i) => {
return "";
};
//从定义看出,最后一个是返回类型
Func<int, string,DateTime> func2 = (i,s) =>
{
return DateTime.Now;
};
}
private static void Test() {
//Console.WriteLine(k);
}
}
}
public class LambdaOther {
//public string name=>"测试";
public string name {
get {
return "测试";
}
}
//public int Id{get;set;}=123
private int _ID=123;
//一个属性,两个
public int Id{
get{
return _ID;
}
set{
_ID=value;
}
}
//public string Get()=>"";
//
//public string Remark
//{
//get =>"ce"
//}
}
总结三点:
第一:lambda离不开委托,就是为委托而生,有了它,委托使用更加方便
第二:lambda还可以快捷声明方法,如下,用VS2012编写,即自带C#5.0,需要VS2015 才可以通过注释部分
注意点:当只有一行语句,lambda表达式可省掉return ,大括号,分号这些
结尾多一嘴,Vs2012对应的是C#5.0版本,但是真正重大功能的,是C#3.0即VS2010中,比如扩展方法,linq等等,如下
https://docs.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-version-history,希望重视C#版本概念,尤其是新增语法,因为c#是一种自实现的语言,很多扩展本身就是通过自身实现的