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 }
浙公网安备 33010602011771号