C#的委托、匿名委托、lambda表达式

时间:2021-03-02 19:26:17


什么是委托:

包含单个方法的委托和函数指针是相似的,不同的是,委托是面向对象的并且是类型安全的。


声明委托类型:

// 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. public delegate bool 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是一个预定义得到泛型委托                
               // public delegate bool 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);   
});