delegate是一种可用于封装命名或匿名方法的引用类型。 请求类似于c的函数指针,但请求是类型的安全性和可靠性。 有关应用委托的信息,请参阅委托和通用委托。 这里介绍委托的几种使用方法。
简单的委托示例:
publicclasstestdelegate { publicdelegatevoiddelegate (对象发送器); 私有delegate _ delegate; publicvoidsetdelegate (删除LG ) {_delegate=dlg; }public void InvokeDelegate () if ) _delegate==null ) {return; }_delegate.invoke () this; }
委托接口实现:
publicclasstestlistenera { staticpublicvoidondelegateinvoked (对象发送器) system.console.writeline (发送器a ' ) }。 }使用方法:
pre name=' code ' class=' cs harp ' testdelegatedlg=new test delegate (; testlistenerala=newtestlistenera (; DLG.set delegate (la.ondelegateinvoked; dlg.InvokeDelegate (;
熟悉代理模式(或代理模式)应该很容易理解这段代码。 用c的语法说明,在TestDelegate中设定回调。
但是,delegate的使用方法不限于此,在TestDelegate中添加代码:
公共语音顾问(delegated LG ) {_delegate =dlg; } publicvoidremovelistener (delegated LG ) {_delegate -=dlg; }
现在,您可以向测试删除添加多个回调。
声明了类,实现了静态委托:
publicclasstestlistenerb { staticpublicvoideventhandler (对象发送器) system.console.writeline ) listenerb ' ); }
你可以像这样使用delegate。
testdelegatedlg=new test delegate (; testlistenerala=newtestlistenera (; DLG.addlistener (la.ondelegateinvoked; DLG.addlistener (testlistenerb.eventhandler; test delegate.delegatelamdadlg=(object sender )={system.console.writeline ) listenerlamdac'}; ); DLG.addlistener(lamdadlg ); DLG.addlistener () objectsender ) ) system.console.writeline ) listenerlamdad ); ); dlg.InvokeDelegate (; 也可以删除部分删除:
DLG.remove listener (testlistenerb.eventhandler ); DLG .移除监听器(lamda DLG ); dlg.InvokeDelegate (; 现在不再调用TestListenerB.EventHandler和lamdaDlg。
也可以删除所有删除。
DLG.set delegate (空);
重新添加。
DLG.addlistener(lamdadlg );
这里可能有疑问,把空值和lamdaDlg加起来没问题吗?
带着这个问题详细看看delegate吧。
我们知道所有delegate都从System.MulticastDelegate继承,后者从System.Delegate继承。
因为System.Delegate是抽象类(abstractclass ),所以一些具体实现是在System.MulticastDelegate中完成的。
这里主要看两种方法Combine和Remove。 可以推测这两种方法都是以静态方式分别调用CombineImpl和RemoveImpl。
组合impl是集成委托的实现,而移除impl是删除委托的实现。
System.Delegate和System.MulticastDelegate都有一种称为GetInvocationList的方法。 此方法返回System.Delegate数组。 数组中有正在参与调用的delegate。
由此可以推测,在System.MulticastDelegate中维护了委托表,在调用CombineImpl时将新的委托添加到该表中,在调用RemoveImpl时从表中删除目标委托。
可以推测,delegate调用operator时将调用System.Delegate的Combine方法,而调用operator -时将调用System.Delegate的Remove方法为delegate赋值时,将调用System.Delegate中的CreateDelegate方法。
回到上一个问题,为什么空值和lamdaDlg可以相加? 我们不需要探究Combine方法是如何实现的,只要简单切换就可以理解
_delegate =dlg; 同等:
_ delegate=(test delegate.delegate ) system.delegate.com bine delegate,dlg );