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},區別是參數前面沒有寫類型. 不寫的話,叫參數類型隱式.會自動認為是調用實例的類型.寫成這種和不寫效果一樣的,所有參數一至,隱式都隱,顯示都顯.
// 還有更廣泛的應用在於,昨時需要一個計算函數,,但又不想建類的情況..
C#Lambda