Lambda表达式详解
lambda表达式在很多语言中应用,lambda表达式可以当作委托中的一种变形,委托的构建方便编程人员能够在程序中传入函数,相当于回掉函数。
lambda表达式可以方便的构造匿名函数,如果代码中里面存有大量小的功能函数,而这些函数只被调用一次,不妨将他们重构成lambda表达式。比如需要计算a+b,那么一般思路初始化,然后计算。lambda表达式可以直接赋值计算。关键让人看的简洁,明白这一段代码是完成一个功能。Lambda表达式为编写匿名方法提供了更简明的函数式的句法,但结果却在编写LINQ查询表达式时变得极其有用,因为它们提供了一个非常紧凑的而且类安全的方式来编写可以当作参数来传递,在以后作运算的函数。所以在对数据库操作时,lambda应用很广。
lambda运算符:所有的lambda表达式都是使用新的lambda运算符“=》”,让人理解为“转到”。运算符将表达式分成两部分:左边指定输入参数,右边是lambda主体表达式。
lambda表达式:
1 一个参数:para=》expr
2 多个表达式:(para1,para2)=》expr。
前面讲过lambda表达式是委托执行的变异体,先有委托,然后才可以在声明对象时,直接执行lambda表达式。
func委托
T是一种参数类型,可以声明类型,也可以直接这样写。
多个参数,前面的参数,最后一个是返回值的类型,这个是必须有的啊。
下面我们分析下。
public class Person { public string name { get; set; } public int Age { get; set; } </span> //声明个person类 } public static class test1 { //扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。 //扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的。 它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。 //扩展方法的要求如下: //1 第一个参数是要扩展或者要操作的类型,这称为"被扩展的类型" //2 为了指定扩展方法,要在被扩展的类型名称前面附加this修饰符 //3 要将方法作为一个扩展方法来访问,要用using指令导入扩展类型的命名空间,或者使扩展类型和调用代码在同一个命名空间中. public static IEnumerable<T> testwhere<T>(this IEnumerable<T> souces, Func<T, bool> predica) { foreach (T item in souces) { if (predica(item)) { //yield计算表达式并以枚举数对象值的形式返回;返回值必须可以隐式转换为迭代器的 yield 类型。 yield return item; } } } } class Program { public static List<Person> PersonList() {//加载person类 List<Person> persons = new List<Person>(); for (int i = 1; i < 10;i++ ) { persons.Add(new Person(){name = i+ "erzi",Age = i,}); } return persons; } //用于委托到lambda变形 delegate int Addsum(int a, int b); static void Main(string[] args) { List<Person> personlist = PersonList(); //where括号中需要传入func函数,这个lambda也可以自己写 //personlist = personlist.Where(p => p.Age > 2).ToList(); List<Person> personlist2 = PersonList(); personlist2 = test1.testwhere(personlist2, p => p.Age > 3).ToList();//测试生成数据 Person[] personarray = personlist.Where(p => p.Age < 7).ToArray(); Person per = personlist.SingleOrDefault(p => p.Age == 6); //lambda表达式用之前需要委托,之后在其应用lambda表达式 Addsum count = (i,j) => i + j; foreach (Person temp in personlist2) { Console.WriteLine(temp.name); } foreach (Person temp in personarray) { Console.WriteLine(temp.name); } Console.ReadKey(); } }
C#里,一个lambda表达式在句法上是写成一个参数列表,随后是 => 符号,随后是表达式在调用时要运算的表达式或者语句块所以,当我们编写这样的lambda表达式时:我们是想表示,我们在定义的Lambda接受一个参数p,要运行的代码表达式返回p.LastName的值是否等于“Guthrie”。 我们将参数命名为p是不相干的,我也可以很容易地将其命名为o,x,foo,或者我想要的任何名字。不象匿名方法要求参数类型是明确地指明的,Lambda表达式允许省略参数类型,而允许它们根据用法来推断出类型。譬如,当我编写 p=>p.LastName == "Guthrie" 这个lambda表达式时,编译器推断出p参数属于Person类型,因为当前的Where扩展方法的对象是个范型的List<Person>集合。Lambda参数的类型可以在编译时和被Visual Studio的intellisense引擎推断出来,这意味着在编写lambda时你将获得完全的intellisense 和编译时检查。譬如,注意当我在下面健入 p. 时,Visual Studio Orcas是如何提供intellisense完成的,因为它知道 p 是 Person类型:
其实针对lambda应用中,类似这种func委托一个用广的,比如在异步委托中。针对控件中我们常常需要加载信息,此处应该用异步,所以在控件上应用异步时需要应用Invoke。此函数需要传入委托。
1. (一)Action和Fun两个委托的不同点:
Action只能委托必须是无返回值的方法
Fun只是委托必须有返回值的方法
泛型委托Action这里指多个类型参数
Action委托:只能委托无返回值(void)的方法。
(2)可以使用此委托以参数形式传递方法,而不用显式声明自定义的委托
泛型委托Func委托,这里可以有一个或多个或者没有参数T,但必须有返回值并返回 TResult 参数所指定的类型的值
(1)必须有指定参数返回值。
2)Lambda 表达式的基础类型是泛型 Func 委托之一。 这样能以参数形式传递 lambda 表达式,而不用显式将其分配给委托。
(3)因为 System.Linq 命名空间中许多类型方法具有 Func 参数,因此可以给这些方法传递 lambda 表达式,而不用显式实例化 Func 委托。