C#Lambda
入 表达式记得学习过,还经常用,可是一但有点时间不用了,再一看却又觉得不熟悉了.看来还是理解有问题.
1.函数的引用
刚开始学习程序时,是函数式的.有各种各样的函数.有时需要将函数作为一个参数传给另一相函数.那时是创建一个到这函数的引用,然后传引用.
fun a(){...;} // 函数a
$ref_a=\a; // 函数a的引用
b($ref_a); // 将a传为参数传给函数b
2.方法的引用
后来学习面向对象语言,不能再随意定义函数.函数必须定义在一个类中.然后函数叫做"类的方法".那么将方法做为参数传给另一个方法要怎么办?
class A{bool af(){...;}} // 类A 有一个方法af
class B{void bf(Func<bool> fun){...;}} // 类B 有一个方法bf
Func<bool> ref_af = a.af; // 为a.af方法建一个委托.a是A的实例
b.bf(ref_af);// 将a.af传递给b.bf方法.b是B的实例
3.对比
发现函数式的传递简洁明了,对象式的很复杂.以前C#为了创建一个方法引用,还需要先建一个委托类型,再实例化这个委托,再将方法绑定到这个委托...后来有了Func Action这些定义好的委托之后变得方便一些.然而有时候只需要一个临时方法,并不希望为这方法再建一个类,连方法名字也不用起.那么就发明了简洁的lambda表达式
lambda实质仍然是函数(方法)引用,它可以一句话包含参数,方法体,返回值.它可直接作为参数写在方法调用.
(int a,int b)=>a+b // 参数是a,b整型 返回值是a+b的结果,整型
(int a,int b)=>new{num1=a,num2=b} // 参数是a,b整型 返回值是含有属性num1,num2的匿名对象
4.用处
接口返回一个JSON格式数据,一般由实体类转换而来,类的属性很多,并不用全部返回,只是用到谁返回谁.
// 例如
class employee{
public string Name{get;set;}
public string Sex{get;set;}
public string Dept{get;set;}
还有N个属性......
}
如果只需要Name值,返回如下JSON即可
[{Name:"tom"},{Name:"jack"}]
但如果不加处理,直接用employee类JOSN返回,则有很多"无用字段"
[{Name:"tom",Sex:null,Dept:null,.....},{Name:"jack",Sex:null,Dept:null,.....}]
最简单的处理办法是循环,取出需要的字段放到一个列表里,然后JSON化这个列表
List<employee> empList=GetData();
List<dynamic> list = new List<dynamic>();
for(var emp in empList)
{
list.add(new{Name=emp.Name});// 取出名称,放到临时列表中
}
return list.ToJson();// JSON化这个列表得到JSON格式数据
// 但是知道Lambda之后可以一句话得到结果
IEnumerable<dynamic> list1= empList.Select(o=>new{Name=o.Name});// 使用 o=>new{Name=o.Name} 这个表达式直接得到临时列表
Select方法是集合对象提供的一个扩展方法,是实例的.
功能说明是 "将序列中的每个元素投射到一个新的窗体中."这句话我没有理解,从它的一个重载方法理解到,参数是一个1参数1返回值的委托,如下:
o=>new{Name=o.Name}
o表示参数(就是empList列表中的一个employee对象实例),=>(读goes to)右边表示新建了一个匿名实例有一个属性Name,值取于o.Name
为什么没写成 (employee o)=>new{Name=o.Name},区别是参数前面没有写类型. 不写的话,叫参数类型隐式.会自动认为是调用实例的类型.写成这种和不写效果一样的,所有参数一至,隐式都隐,显示都显.
// 还有更广泛的应用在于,临时需要一个计算函数,,但又不想建类的情况..