在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);
部落格園大道至簡
<a href="http://www.cnblogs.com/jams742003/" target="_blank">http://www.cnblogs.com/jams742003/</a>
轉載請注明:部落格園