在C#使用字典存储事件示例及实现自定义事件访问器
使用字典存储事件实例
accessor-declarations的一种用法是公开很多事件但不为每个事件分配字段,而是使用字典来存储这些事件实例。这只在具有很多事件但您预计大多数事件都不会实现时才有用。
publicdelegatevoidEventHandler1(inti); publicdelegatevoidEventHandler2(strings); publicclassPropertyEventsSample { privateSystem.Collections.Generic.Dictionary<string,System.Delegate>eventTable; publicPropertyEventsSample() { eventTable=newSystem.Collections.Generic.Dictionary<string,System.Delegate>(); eventTable.Add("Event1",null); eventTable.Add("Event2",null); } publiceventEventHandler1Event1 { add { lock(eventTable) { eventTable["Event1"]=(EventHandler1)eventTable["Event1"]+value; } } remove { lock(eventTable) { eventTable["Event1"]=(EventHandler1)eventTable["Event1"]-value; } } } publiceventEventHandler2Event2 { add { lock(eventTable) { eventTable["Event2"]=(EventHandler2)eventTable["Event2"]+value; } } remove { lock(eventTable) { eventTable["Event2"]=(EventHandler2)eventTable["Event2"]-value; } } } internalvoidRaiseEvent1(inti) { EventHandler1handler1; if(null!=(handler1=(EventHandler1)eventTable["Event1"])) { handler1(i); } } internalvoidRaiseEvent2(strings) { EventHandler2handler2; if(null!=(handler2=(EventHandler2)eventTable["Event2"])) { handler2(s); } } } publicclassTestClass { publicstaticvoidDelegate1Method(inti) { System.Console.WriteLine(i); } publicstaticvoidDelegate2Method(strings) { System.Console.WriteLine(s); } staticvoidMain() { PropertyEventsSamplep=newPropertyEventsSample(); p.Event1+=newEventHandler1(TestClass.Delegate1Method); p.Event1+=newEventHandler1(TestClass.Delegate1Method); p.Event1-=newEventHandler1(TestClass.Delegate1Method); p.RaiseEvent1(2); p.Event2+=newEventHandler2(TestClass.Delegate2Method); p.Event2+=newEventHandler2(TestClass.Delegate2Method); p.Event2-=newEventHandler2(TestClass.Delegate2Method); p.RaiseEvent2("TestString"); //Keeptheconsolewindowopenindebugmode. System.Console.WriteLine("Pressanykeytoexit."); System.Console.ReadKey(); } }
输出:
2 TestString
实现自定义事件访问器
事件是特殊类型的多路广播委托,只能从声明它的类中调用。客户端代码通过提供对应在引发事件时调用的方法的引用来订阅事件。这些方法通过事件访问器添加到委托的调用列表中,事件访问器类似于属性访问器,不同之处在于事件访问器被命名为add和remove。在大多数情况下都不需要提供自定义的事件访问器。如果您在代码中没有提供自定义的事件访问器,编译器会自动添加事件访问器。但在某些情况下,您可能需要提供自定义行为。下面的示例演示如何实现自定义的add和remove事件访问器。虽然可以替换这些访问器内的任何代码,但建议您在添加或移除新的事件处理程序方法之前先锁定该事件。
eventEventHandlerIDrawingObject.OnDraw { add { lock(PreDrawEvent) { PreDrawEvent+=value; } } remove { lock(PreDrawEvent) { PreDrawEvent-=value; } } }