1. 程式人生 > >C#的委託、匿名委託、lambda表示式

C#的委託、匿名委託、lambda表示式

什麼是委託:

包含單個方法的委託和函式指標是相似的,不同的是,委託是面向物件的並且是型別安全的。

宣告委託型別:

// Declare a delegate.

delegate void Del(string str);

宣告委託和宣告方法差不多,兩個不通點就在於

委託以:delegate關鍵詞開頭。沒有方法主體

建立委託物件:

// Declare a method with the same signature as the delegate.

static void Notify(string name){ Console.WriteLine("Notification received for: {0}", name);}


// Create an instance of the delegate.

Del del1 = new Del(Notify);

或者

Del del2 = Notify;

組合委託:

mydel  dela=方法;

mydel delb=方法

mydel delc=dela+delb;

委託增減方法

mydel del=方法//建立初始化

del+=方法;//增加方法

del-=方法;//刪減方法

使用匿名方法來建立委託物件

// Instantiate Del by using an anonymous method.

Del del3 = delegate(string name) { Console.WriteLine(

"Notification received for: {0}", name); };

使用Lambda表示式來建立委託物件

// Instantiate Del by using a lambda expression.

Del del4 = name => { Console.WriteLine("Notification received for: {0}", name); };

  1. publicdelegatebool Predicate<in T>(T obj);  

21         //傳統的呼叫委託的例項
22         static void FindListDelegate()
23 { 24 //建立泛型list類 25 List<string> list = new List<string>(); 26 27 list.AddRange(new string[] { "asp.net課程","Java課程","123" }); 28 Predicate<string> findPredicate = new Predicate<string>(IsBookCategory);
               //這裡Predicate是一個預定義得到泛型委託                
               // publicdelegatebool Predicate<in T>(T obj);

29             List<string> bookCategory = list.FindAll(findPredicate);
30 
31             foreach (string str in bookCategory)
32             {
33                 Console.WriteLine("{0}\t", str);
34             }
35         }
36         //謂詞方法,傳遞給FindALl進行書籍分類判斷
37         static bool IsBookCategory(string str)
38         {
39             return str.EndsWith("課程") ? true : false;
40         }
41         
42         //使用匿名方法來進行搜尋過程
44         static void FindListAnonymousMethod()
45         {
46             //先建立泛型list類
47             List<string> list = new List<string>();
48             list.AddRange(new string[] { "asp.net課程", "MVC課程,123" });
49 
50             //在這裡,使用匿名方法直接為委託建立一個程式碼塊,而不用去建立單獨的方法
51 
52             List<string> bookCategory = list.FindAll(delegate(string str)
53                 {
54                     return str.EndsWith("課程") ? true : false;
55                 }
56                 );
57             foreach (string str in bookCategory)
58             {
59                 Console.WriteLine("{0}\t", str);
60             }
61         }
62         //使用lambda來實現搜尋過程
63         static void FindListLambdaExpression()
64         {
65  
66             //先建立一個泛型的list類
67             List<string> list = new List<string>();
68             list.AddRange(new string[] { "asp.net課程", "MVC課程","123" });
69             //在這裡使用lambda來建立一個委託方法
70 
71             List<string> bookCategory = list.FindAll((string str) => str.EndsWith("課程"));
72 
73             foreach (string str in bookCategory)
74             {
75                 Console.WriteLine("{0}\t", str);
76             }
77         }

起先,  1:   寫一個獨立的方法,然後賦值給委託;

     2: 後來覺得程式碼多了,搞一個匿名方法,省去了賦值的步驟;

     3: 再後來,匿名方法也麻煩,就搞了一個lambda表示式,lambda表示式比匿名方法更簡單易寫。

但是歸根結底,Lamdba 表示式也是一個委託型別。

值得注意的是,無論是傳統委託還是匿名委託還是Lambda表示式,都要保證其返回值剛好是呼叫委託的那個函式的引數需要的型別。

比如這裡呼叫委託的findAll()函式的引數需要的是bool型別。

又比如下面的程式碼使用lambda表示式來建立執行緒,Thread()的引數需要是個函式型別,所以這裡lambda表示式返回的也是個函式型別{}。

Thread t = new Thread(() =>   
{   
AddIt AddDelegate = new AddIt(AddItem);   
this.Invoke(AddDelegate);   
});