C#委托 事件 小计

  委托 、事件, 一直是个门槛,实际应用中基本上没有使用,但是当自己写一套方法时候,了解就有必要了!

  委托:委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。

通用例子:

 1 public void GreetPeople(string name,int type )
 2 {
 3     if(type==1)
 4         EnglishGreeting(name);
 5     else 
 6          ChineseGreeting(name);
 7 }
 8 public void EnglishGreeting(string name)
 9 {
10     Console.WriteLine("Morning, " + name);
11 }
12 public void ChineseGreeting(string name)
13 {
14     Console.WriteLine("早上好, " + name);
15 }
 1 namespace Delegate {
 2 //定义委托,它定义了可以代表的方法的类型
 3 public delegate void GreetingDelegate(string name);
 4 //新建的GreetingManager类
 5 public class GreetingManager{
 6 public GreetingDelegate delegate1;
 7 
 8 public void GreetPeople(string name, GreetingDelegate MakeGreeting) {
 9 //MakeGreeting(name);
10 
11 if(delegate1!=null){ //如果有方法注册委托变量
12 delegate1(name); //通过委托调用方法
13 }
14 
15 }
16 }
17 class Program {
18 private static void EnglishGreeting(string name) {
19 Console.WriteLine("Morning, " + name);
20 }
21 private static void ChineseGreeting(string name) {
22 Console.WriteLine("早上好, " + name);
23 }
24 static void Main(string[] args) {
25    GreetingManager gm = new GreetingManager();
26     gm.delegate1 = EnglishGreeting;
27     gm.delegate1 += ChineseGreeting;
28     gm.GreetPeople("Jimmy Zhang"); 
29 }
30 }
31 }

这个例子中可以看出 可以对委托进行方法的绑定、解除 (+= 、 -=)

这样会有一个问题的,那就是我们可以再类外面随意的干扰,破坏这个委托,如:

gm.delegate1=null;

这样就有了事件,对一个属性 保护使用封装

对委托进行保护则使用事件

在类的内部,不管你声明它是public还是protected,它总是private的。

在类的外部,注册方法 “+=”和注销方法“-=”的访问限定符()与你在声明事件时使用的访问符相同

说明我们没法对事件用赋值[=] 号来进行注册,这就避免了破坏直接委托链的指针指向了

代码:

 1 public event GreetingDelegate MakeGreet;
 2 public void GreetPeople(string name) {
 3 MakeGreet(name);
 4 }
 5 }
 6 
 7 static void Main(string[] args) {
 8 GreetingManager gm = new GreetingManager();
 9 gm.MakeGreet = EnglishGreeting; 
10 // 编译错误1 只能使用+=  -= 之前绑定的多个方法不受影响
11 gm.MakeGreet += ChineseGreeting;
12 gm.GreetPeople("Jimmy Zhang");
13 }

 http://www.cnblogs.com/leslies2/archive/2012/03/22/2389318.html这个要搞搞

委托的协变

 1 public class Worker
 2      {.......}
 3      public class Manager:Worker
 4      {.......}
 5  
 6       class Program
 7      {
 8          public delegate Worker GetWorkerHandler(int id);
 9          //在 Framework2.0 以上,委托 GetWorkerHandler 可绑定 GetWorker 与 GetManager 两个方法10  
10          public static Worker GetWorker(int id)
11          {
12              Worker worker = new Worker();
13              return worker;
14          }
15  
16          public static Manager GetManager(int id)
17          {
18              Manager manager = new Manager();
19              return manager;
20          }
21  
22         static void Main(string[] args)
23         {
24             GetWorkerHandler workerHandler = new GetWorkerHandler(GetWorker);
25             Worker worker=workerHandler(1);
26             GetWorkerHandler managerHandler = new GetWorkerHandler(GetManager);
27             Manager manager = managerHandler(2) as Manager;
28             Console.ReadKey();
29         }
30      }
委托GetWorkerHandler 使用GetWorker  将返回一个Worker   但是使用委托传递GetManager也将返回一个可以转为Manager的Worker
委托的逆变
 1 class Program
 2     {
 3         public delegate void Handler(object obj);
 4 
 5         public static void GetMessage(object message)
 6         {
 7             if (message is string)
 8                 Console.WriteLine("His name is : " + message.ToString());
 9             if (message is int)
10                 Console.WriteLine("His age is : " + message.ToString());
11         }
12 
13         static void Main(string[] args)
14         {
15             Handler handler = new Handler(GetMessage);
16             handler(29);
17             Console.ReadKey();
18         }
19    }

委托逆变是从方法的参数上面做手脚,可以接受未知类型的参数

泛型委托

委托逆变虽然实用,但如果都以 object 作为参数,则需要每次都对参数进行类型的判断,这不禁令人感到厌烦。

为此,泛型委托应运而生,泛型委托有着委托逆变的优点,同时利用泛型的特性,可以使一个委托绑定多个不同类型参数的方法,而且在方法中不需要使用 is 进行类型判断,从而简化了代码。

 1 class Program
 2     {
 3         public delegate void Handler<T>(T obj);
 4 
 5         public static void GetWorkerWages(Worker worker)
 6         {
 7             Console.WriteLine("Worker's total wages is " + worker.Wages);
 8         }
 9 
10         public static void GetManagerWages(Manager manager)
11         {
12             Console.WriteLine("Manager's total wages is "+manager.Wages);
13         }
14 
15         static void Main(string[] args)
16         {
17             Handler<Worker> workerHander = new Handler<Worker>(GetWorkerWages);
18             Worker worker = new Worker();
19             worker.Wages = 3000;
20             workerHander(worker);
21 
22             Handler<Manager> managerHandler = new Handler<Manager>(GetManagerWages);
23             Manager manager = new Manager();
24             manager.Wages = 4500;
25             managerHandler(manager);
26 
27             Console.ReadKey();
28         }
29     }

 



posted @ 2016-02-27 16:15  Enjoy Life  阅读(112)  评论(0)    收藏  举报