2020-11-16

C#Lambda表达式的理解应用
一、Lambda表达式的演变过程
Lambda表达式可以理解为是一个匿名函数,Lambda表达式可以包含表达式和语句,并且可以用于创建委托,以及C#编译器也能将它转换成表达式树。

对于Lambda表达式中都会使用这个运算符——“=>”,它读成“goes to”,该运算符的左边为输入参数,右边是表达式或者语句块。
using System;

namespace Lambda
{
class Program
{
//Lambda表达式使用演示
static void Main(string[] args)
{
//Lambda表达式的演变过程
//下面是C#1中创建委托实例的代码
Func<string,int> delegatetest1 = new Func<string,int>(Callbackmethod);

		//C#2中用匿名方法来创建委托实例,此时就不需要额外定义回调方法Callbackmethod
		Func<string,int> delegatetest2 = delegate(string text)
		{
			return text.Length;
		};

		//C#3中使用Lambda表达式来创建委托实例
		Func<string,int> delegatetest3 = (string text) => text.Length;

		可以省略参数类型string,把上面代码在简化为:
		Func<string,int> delegatetest4 = text => text.Length;

		//调用委托
		Console.WriteLine("使用Lambda表达式返回字符串的长度为:“ + delegatetest("learning hard"));
		
	}
}

}

二、Lambda表达式的使用
using System;
using System.Windows.Forms;

namespace Lambda表达式来记录事件Demo
{
class Program
{
static void Mian(string[] args)
{
//新建一个button实例
Button button1 = new Button() {Text = “点击我”};

		//C# 2 中使用匿名方法来订阅事件
		//button1.Click += delegate(object sender,EventArgs e)
		//{
		//	ReportEvent("Click事件",sender,e);
		//};
		//button1.KeyPress += delegate(object sender,KeyPressEventArgs e)
		//{
		//	ReportEvent("KeyPress事件,即键盘按下事件",sender,e);
		//};

		//C# 3Lambda表达式方式来订阅事件
		//与上面使用匿名方法来订阅事件是不是简单了很多,并且也直观了
		button1.Click += (sender,e) => ReportEvent("Click事件",sender,e);
		button1.KeyPress += (sender,e) => ReportEvent("KeyPress事件,即键盘按下事件",sender,e);

		//C# 3之前初始化对象时使用下面代码
		//Form from = new Form();
		//form.Name = "在控制台中创建的窗体";
		//form.AutoSize = true;
		//form.Controls.Add(button1);

		//C# 3中使用对象初始化器
		//与上面代码的比较中,也可以看出使用对象初始化之后代码简化了很多
		Form form = new Form{Name = "在控制台中创建的窗体",AutoSize = true,Controls = {button1}};

		//运行窗体
		Application.Run(form);
	}

	//记录事件的回调方法
	private static void ReportEvent(string title,object sender,EventArrgs e)
	{
		Console.WriteLine("发生的事件为:{0}", title);
        Console.WriteLine("发生事件的对象为:{0}", sender);
        Console.WriteLine("发生事件参数为: {0}", e.GetType());
        Console.WriteLine();
        Console.WriteLine();
	}
}

}

三、表达式树
上面指出Lambda表达式除了可以用来创建委托外,C#编译器还可以将他们转换成表达式树—用于表示Lambda表达式逻辑的一种数据结构,表达式树也可以称作表达式目录树,它将代码表示成一个对象树,而不是可执行的代码。对于刚接触表达式树的可能有疑问—为什么需要把Lambda表达式转化为表达式目录树?对于表达式树的提出主要是为后面Linq to SQL做铺垫,一个Linq to SQL的查询语句并不是在C#的程序中执行的,而是C#编译器把它转化为SQL语句,把返回的结果在返回给一个IQueryable集合,所以Linq to SQL也采用了通常的ORM(Object - Relationship - Mapping)来设计的,相当于是一个ORM框架,不过这个框架只能与微软的SQL server数据库进行映射,对于其他类型的数据库却不可以,然而很多其他开发人员却对此进行了一些扩展,扩展了对其他数据库的支持。
下面先看看如何把Lambda表达式转化为表达式目录树
using System;
using System.Linq.Expressions;

namespace表达式树Demo
{
class Program
{
//表达式树的演示
//static void Main(string[] args)
{
#region 将Lambda表达式转换为表达式树演示
//将Lambda表达式转换为Express的表达式树
//此时express不是可执行的代码,他现在是一个表达式树的数据结构
Console.WriteLine(“将Lambda表达式转化为表达式树的演示:”);
Expression<Func<int, int,int>> expression = (a,b) => a+b;

		//获得表达式树的参数
		Console.WriteLine("参数1:{0},参数2:{1}",expression.Parameters[0],expression.Parameters[1]);

		//既然叫做树,那肯定有左右节点
		//获取表达式树的主体部分
		BinaryExpression body = (BinaryExpression) expression.Body;

		//左节点,每个节点本身就是一个表达式对象
		ParameterExpression left = (ParameterExpression)body.Left;

		//右节点
		ParameterExpression right = (ParameterExpression)body.Right;

		Console.WriteLine("表达式主体为:");
        Console.WriteLine(expression.Body);
        Console.WriteLine("表达式树左节点为:{0}{4} 节点类型为:{1}{4}{4} 表达式右节点为:{2}{4} 节点类型为:{3}{4}", left.Name, left.NodeType, right.Name, right.NodeType,Environment.NewLine);
        Console.Read();
        #endregion 

        #region 把表达式树转化回可执行代码

        // Compile方法生成Lambda表达式的委托
        Console.WriteLine("按下Enter键进入将表达式树转换为Lambda表达式的委托演示:");
        int result = expression.Compile()(2, 3);
        Console.WriteLine("调用Lambda表达式委托结果为:" + result);
        Console.ReadKey();
        #endregion
	}
}

}

补充:
1.匿名函数不等于匿名方法,匿名函数包含了匿名方法和Lambda表达式这两种概念。
2.Lambda作为表达式,可以被C#编译器转换为委托,也可以被编译器转换为表达式树,匿名方法只能转换为委托。
3.两者的共同点是都能被编译器转换为委托,Lambda表达式能完成几乎所有匿名方法能完成的事。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值