导航

委托的三种用法

Posted on 2011-12-13 22:43  Jessie.M  阅读(363)  评论(0编辑  收藏  举报

在《C#入门经典》第四版中看到,定义和使用委托的方法,通常是写好相应的委托函数,然后将函数名传入。但是这样在进入被委托执行的函数时,需要使用的变量又不可见,必须添加成员变量。

例如,User是我定义的一个用户类,UserManagement类中的成员变量UserList是一个List<User>对象,储存一个用户列表。我需要在UserManagement类中加一个RemoveUser成员函数,以用户的ID为索引在UserList中找到这个User并删除它。

考虑使用.NET类库中泛型类LIST<T>的函数:T Find(Predicate<T> match),查MSDN发现Predicate<T>是一个以T对象为参数,返回bool的委托:

  1. public delegate bool Predicate<T>(  
  2.     T obj  
  3. )  

Find函数将List<T>中的每一个T类对象作为参数传给match,直到第一个使match返回true的对象停止,返回这个对象T。

 

为了使用这个函数,我这样写:

1.在类中添加变量 

  1. String TargetID;  

2.定义Predicate类的一个对象:

  1. Predicate<User> p1=new Predicate<User>(FindByID);  

 

3.定义函数:

  1. bool FindByID(User user)  
  2. {  
  3.     if(user.ID==TargetID)  
  4.     return true;  
  5.     else  
  6.         return false;  
  7. }  


 

4.得以实现RemoveUser函数:

  1. public void RemoveUser(string TargetID)  
  2. {  
  3.     this.TargetID=TargetID;  
  4.     User TargetUser=UserList.Find(p1);  
  5.     UserList.Remove(TargetUser);  
  6. }  


 

但是这样让UserManagement类中凭空增添了一个成员变量TargetID,不太好。

 

而匿名方法可以这样实现:

直接定义RemoveUser函数:

  1. public void RemoveUser(string TargetID)  
  2.         {  
  3.               
  4.             User TargetUser = UserList.Find(  
  5.                 delegate(User u)  
  6.                 {  
  7.                     if (u.ID == ID)  
  8.                         return true;  
  9.                     else  
  10.                         return false;    
  11.                 });  
  12.             UserList.Remove(TargetUser);   
  13.         }  

在Find参数中直接传入匿名委托,在实现代码中可以直接使用此函数中的TargetID作为参数,而避免添加多余的成员变量用于传递参数。

 

此外,还可以使用lambda表达式替代匿名方法(.NET3.0以后便可以用lambda表达式替代匿名方法):

 1 public void RemoveUser(string TargetID)  
2 {
3
4 User TargetUser = UserList.Find(
5 u=>
6 {
7 if (u.ID == ID)
8 return true;
9 else
10 return false;
11 });
12 UserList.Remove(TargetUser);
13 }
14
15