匿名方法与lambda表达式
在C#1.0中的委托必须显式的用一方法签名和声明委托相匹配的方法进行初试化。如:
delegate bool IsDisplay(string s);
static bool IsTrue(string flag)
{
return flag == "true" ? true : false;
}
static void Display(IsDisplay isDisplay, string str)
{
if (isDisplay(str))
{
Console.WriteLine("Hello World!");
}
}
static void Main(string[] args)
{
string str = "true";
IsDisplay display = new IsDisplay(IsTrue);
Display(display, str);
Console.ReadLine();
}
在C#2.0中出现了匿名方法,匿名方法增强了委托功能,以关键字delegate开头,后面直接跟一小括号,没有方法名称,匿名方法还允许原本用委托实例传入的参数直接以内联代码块的方式提供。如下
delegate bool IsDisplay(string s);
static void Display(IsDisplay isDisplay, string str)
{
if (isDisplay(str))
{
Console.WriteLine("Hello World!");
}
}
static void Main(string[] args)
{
string str = "true";
Display(delegate(string s)
{
return str == "true" ? true : false;
}, str);
Console.ReadLine();
}
C#3.0引入了lambda表达式,lambda表达式不但能实现匿名方法所能实现的功能,而且代码更简洁,尽展函数编程思想的魅力。lambda表达式可以说是匿名的方法的超集,除了具备匿名方法的功能外,还有一些特有的魅力,先看下lambda表达式修改后的方法,
delegate bool IsDisplay(string s);
static void Display(IsDisplay isDisplay, string str)
{
if (isDisplay(str))
{
Console.WriteLine("Hello World!");
}
}
static void Main(string[] args)
{
string str = "true";
Display(s =>s=="true"?true:false, str);
Console.ReadLine();
}
(1) lambda表达式能够推测出参数的类型,而不用显示声明参数类型(一开始不习惯,有点不爽,时间久了,就习惯了)。
(2) lambda表达式能够用语句块或者表达式做为方法体,匿名方法只能用语句块。
(3) 带有表达式体的lambda表达式可以转换为表达式树。
Lambda表达式的格式如下,
Lambda表达式
“=>”右边是表达式的叫做表达式lambda。
(x)=>x+1
当只有一个参数时,可以省略括号,否则必须要有括号,可以写成
x=>x+1,(x,y)=>x+y
如果觉得编译器难于推断出类型,可以显示的指定类型
(int x, string s) => s.Length > x
使用空括号时,可以指定零个参数
()=>method()
Lambda语句
“=>”右边是{}的叫做语句lambda。
x=>{ return x+1; }
(int x, string s) => { return s.Length > x; }
Lambda表达式树
具有表达式体的lambda可以转换成表达式树。
写了一个小demo,关键地方添加了注释,
static void Main(string[] args)
{
//表达式树
Expression<Func<int, int,int>> exprTree = (x,y)=> x+y;
//Expression<TDelegate> 类型提供 Compile 方法,
//该方法将表达式树表示的代码编译成一个可执行委托。
Func<int, int, int> result = exprTree.Compile();
Console.WriteLine(result(6,7));
//分解表达式树的各个部分
ParameterExpression p1 = (ParameterExpression)exprTree.Parameters[0];
ParameterExpression p2 = (ParameterExpression)exprTree.Parameters[1];
BinaryExpression operation = (BinaryExpression)exprTree.Body;
Console.WriteLine("Decomposed expression: ({0},{1}) => {0}{2} {1}",
p1.Name,p2.Name, operation.NodeType);
//使用 API 创建一个表示 lambda 表达式 (x,y)=> x+y 的表达式树
ParameterExpression xParam = Expression.Parameter(typeof(int), "x");
ParameterExpression yParam = Expression.Parameter(typeof(int), "y");
BinaryExpression addNum = Expression.Add(xParam, yParam);
Expression<Func<int, int,int>> lambda1 =
Expression.Lambda<Func<int,int,int>>(
addNum,
new ParameterExpression[] { xParam,yParam });
Console.WriteLine(lambda1.Compile()(1, 2));
Console.ReadLine();
}