浅析C#之——Observer, Delegate和event(2)
接下来说一下Delegate
先介绍一下Delegate类:
Delegate——委托,是C#中对于函数指针进行封装后的对象,因为C#和JAVA一样都不允许直接使用指针这种高效但危险的东西,所以就用Delegate对象将其封装了起来以增加其使用的安全性;此外,比起直接使用字段,使用对象会更为方便,因为有了对象的封装后,就可以在对象内部预设需要的方法,为外部的调用增添许多便利。
创建委托时,delegate修饰符使其后类型继承MulticastDelegate,该基类提供委托以赋值,添加委托,移除委托和调用委托方法等操作,具体更多功能可查阅MSDN。
先写一个关于使用Delegate的例子:delegate.cs
using System;// 创建一个delegatedelegate int MyHandler(int d1, int d2); class Test{public static int Add(int x, int y){Console.WriteLine("Add has been invoked..");return x+y;}public int Minus(int x, int y){Console.WriteLine("Minus has been invoked..");return x-y;}public static void Main(){Console.WriteLine("mh1:=====================================");MyHandler mh1 = new MyHandler(Test.Add);//绑定静态方法;Console.WriteLine("Outcome1: "+ mh1(100, 200));//==>mh1.Invoke(100, 200); ==> {jump Test.Add;}Console.WriteLine();Console.WriteLine("mh2:=====================================");Test t = new Test();MyHandler mh2 = new MyHandler(t.Minus);//绑定动态方法,这里其实传了两个参数:t和&Minus;Console.WriteLine("Outcome2: "+ mh2(100, 50));Console.WriteLine();Console.WriteLine("mh3:=====================================");MyHandler mh3 = mh1 + mh2;// ;构建委托链;有序的;Console.WriteLine("Outcome3: "+ mh3(200, 100));//依次执行mh1,mh2;返回值是最后一个委托方法的返回值,在此为mh2的返回值;Console.WriteLine();Console.WriteLine("mh4:=====================================");MyHandler mh4 = mh1 + mh2 + mh3;Delegate[] mhs = mh4.GetInvocationList(); //使用Delegate的GetInvocationList()方法可以数组的形式获得委托链中的每一个委托,从而实现对于委托链的随机访问;Console.WriteLine(mhs);for(int i = 0; i<mhs.Length; i++) //遍历委托链;{MyHandler tempHandler =(MyHandler)mhs[i];Console.WriteLine("outcome4: " + i + " " + tempHandler(200, 100));}Console.WriteLine();Console.WriteLine("mh5:=====================================");MyHandler mh5 = delegate(int x, int y){ //绑定匿名方法;Console.WriteLine("匿名方法:");return x*y;};Console.WriteLine("Outcome5: " + mh5(100,200));}}
class MyHandler : MulticastDelegate{//构造器;public MyHandler(Object object, IntPtr method);//这个方法和源代码指定的原型一样;public virtual void Invoke(int d1, int d2);//以下方法实现了对回调方法的异步回调,具体还没有研究过。。。public virtual IAsyncResult BeginInvoke(...);public irtual void EndInvoke(...);} //MulticastDelegate内最主要的是包含了三个静态字段:class MulticastDelegate{private Object _target; //这个字段用来指出要传给实例方法的隐式参数this的值;//当委托对象包装的是一个静态方法时,这个字段为null;//当委托对象包装一个实例方法时,这个字段引用的是回调函数要操作的对象;private IntPtr _method;//一个内部的整数值,CLR用它标示要回调的方法;可以理解为一个函数指针;private Object _invocationList;//用来指向委托链中的下一个委托对象;//...}
Console.WriteLine("mh2:=====================================");Test t = new Test();MyHandler mh2 = new MyHandler(t.Minus);//绑定动态方法,这里其实传了两个参数:t和&Minus;Console.WriteLine("Outcome2: "+ mh2(100, 50));Console.WriteLine();
mh2.Invoke(100,50)
using System;//using System.Collections;interface ReceiveMessage{void storeMessage(String message);}//创建委托类型;delegate void ReceiverList(String message);class MessageCenter{private String messageString; // MessageCenter用来缓存消息的String字段;//private ArrayList receiverList = new ArrayList();private ReceiverList receiverList; //has a delegate;//添加消息接受者;public void addReceiver(ReceiveMessage receiver){//receiverList.Add(receiver);receiverList += new ReceiverList(receiver.storeMessage);}//移除消息接受者;public void removeReceiver(ReceiveMessage receiver){//receiverList.Remove(receiver);receiverList -= new ReceiverList(receiver.storeMessage);}// 新建消息;public void newMessage(String message){Console.WriteLine("New message: " + message + "... [MessageCenter]" );this.messageString = message;}// 通知MessageStore有新消息,将其备份入MessageStore;//public void notice(MessageStore messageStore)/*public void notice(ReceiveMessage messageStore) //将对象参数类型换成接口类型;{//messageStore.MessageString = this.messageString;//Console.WriteLine("Message: '" + messageString + "' have been stored in MessageStore...");messageStore.storeMessage(this.messageString);}*/public void notice()//// 通知所有已注册的receiver有新消息,并调用其storeMessage方法;{/*foreach(Object receiver in receiverList){(receiver as ReceiveMessage).storeMessage(this.messageString);}*/this.receiverList(this.messageString);}}class MessageStore : ReceiveMessage{private String messageString;// MessageStore用户存储消息的String字段;// 其实应该是一个String容器用来存储多条消息,不过在此为了简单只放一条消息;public String MessageString{get{return messageString;}set{this.messageString = value;}}/*public void storeMessage(String message) { this.messageString = message; Console.WriteLine("Message: '" + this.messageString + "' have been stored in MessageStore..."); } */ public void storeMessage(String message) //实现接口方法storeMessage(String message); { this.messageString = message; Console.WriteLine("Message: '" + this.messageString + "' have been stored in MessageStore..."); }// 列出MessageStore中已存储的消息;public void listMessages(){Console.WriteLine("Stored message1: '" + this.messageString + "'...[MessageStore]");}}class MessageChecker : ReceiveMessage{private String checkResult;public void storeMessage(String message) //实现接口方法storeMessage(String message);{this.checkResult = "OK!";Console.WriteLine("The message: '" + message + "' has been checked...");}public void showCheckResult(){Console.WriteLine("The checkResule is: " + this.checkResult + " [MEssageChecker]");}}class Test{public static void Main(){MessageCenter messageCenter = new MessageCenter();MessageStore messageStore = new MessageStore();MessageChecker messageChecker = new MessageChecker();messageCenter.addReceiver(messageStore);messageCenter.addReceiver(messageChecker);messageCenter.newMessage("Hello world!"); //新建消息Hello world;//messageCenter.notice(messageStore);//通知messageStore有消息需要存储;messageCenter.notice();messageStore.listMessages();//列出messageStore中已经存储的消息;messageChecker.showCheckResult(); //显示messageChecker的checkResule;}}