什么是委托:
包含单个方法的委托和函数指针是相似的,不同的是,委托是面向对象的并且是类型安全的。
声明委托类型:
// 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); };
- 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); });