天天看點

Lambda說法——(一)追究

在2.0之前的版本中,如果要聲明委托,要通過命名方法來實作。而2.0開始引入了匿名方法,在3.0及更高版本中,提供了lambda來取代匿名方法,作為編寫内聯代碼的首選方式。

(一)通過命名方法來聲明委托

delegate void PrintName(string strName);

public void NomalDelegate()

{

    PrintName pp = ShowName; 

    pp("John");

public void ShowName(string strName)

    Console.WriteLine("Hello,"+strName);

}

聲名委托,不傳回值,帶有一個串型參數。建立ShowName方法的委托對象pp,通過pp來代理ShowName方法的全部功能。

這是在2.0之前版本中支援。

(二)通過匿名方法來聲明委托

public void AnonymousDelegate()

   PrintName pp = delegate(string strName)

   {

       Console.WriteLine("Hello," + strName);

   }; 

   pp("John");

這裡省略了ShowName方法,通過匿名方法對這個方法做了抽象,使這個方法沒有了意義,但執行相同的功能。

匿名方法提供一種内聯代碼編寫的首選方式。因為是内聯的,是以,這裡要添加分号,來做了一個表達式的結束。

在2.0中,開始增加了對匿名方法的支援。

(三)通過lambda表達式來建立委托

public void LambdaDelegate()

    PrintName pp = strName => Console.WriteLine("Hello," + strName);

比較一下匿名方法與lambda表達式。

PrintName p1 = delegate(string strName){Console.WriteLine("Hello," + strName);};

PrintName p2 =                 strName => Console.WriteLine("Hello," + strName);

匿名方法參數由lambda左邊參數清單指定,代碼段{}隐藏(對于多條語句的,要添加{},如(a, b) => { Console.WriteLine(a); Console.WriteLine(b); };)。goesto(=>)可以了解為分隔符,用于區分方法參數與方法體。而參數類型string因為匿名類型的原因隐藏(當然,也可以用強類型來指定類型,但須加(),例如(string strName))。對于單參數,()可以省略;對于多個參數,要添加(),如(a,b);對于零個參數,也要添加(),如()。

(四)Lambda表達式解讀

(1)x=>x==5

這個表達式實相當于方法

bool XXX(int x)

    if(x==5)return true;

        return false;

它用于傳回bool型值。但這個表達是一個委托類型。通過Func<>方法委托來實作。如下:

Func<int, bool> fun = x => x == 5;

bool bSign=fun(5);

(2)n => n % 2 == 1

這個部分取自以下場景:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

int oddNumbers = numbers.Count(n => n % 2 == 1);

通過以上場景判斷,n % 2 == 1相當于:

bool XXX(int n)

    if (n % 2 == 1) return true;

通過Func委托方法實作:

Func<int, bool> fun = n => n % 2 == 1;

而Count方法有兩個重載:

public static int Count<TSource>(this IEnumerable<TSource> source)

public static int Count<TSource>(this IEnumerable<TSource> source,Func<TSource, bool> predicate)

這種方法叫做擴充方法。而這個場景應用的就是第二個擴充方法,就是實作IEnumerable泛型接口的數組,來統計用來滿足條件n % 2 == 1的元素的個數,而這個參數就是一個Func<TSource, bool>類型的委托執行個體,就是我們的:

也就是查找奇數的個數。

(3)n => n < 6

numbers.TakeWhile(n => n < 6);

還是這個場景:

var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6);

通過場景分析,可以得到n=>n<6的命名方法:

   if (n<6) return true;

     return false;

通過Func委托實作:

Func<int, bool> fun = n => n<6;

TakeWhile方法也是擴充方法:

public static IEnumerable<TSource> TakeWhile<TSource>(this IEnumerable<TSource> source,

    Func<TSource, bool> predicate

)

    Func<TSource, int, bool> predicate

而我們用到的就是第一個,它的功能定義為:隻要滿足指定的條件,就會傳回序列的元素,然後跳過剩餘的元素。

是以它傳回的是一個Ienumerable泛型接口的泛型集。而上一個例子中的Count傳回的則是一個int值。

foreach (int i in firstNumbersLessThan6)

    Console.WriteLine(i);

部落格園大道至簡

http://www.cnblogs.com/jams742003/

轉載請注明:部落格園

繼續閱讀