如何:实现接口事件
接口可声明事件。下面的示例演示如何在类中实现接口事件。接口事件的实现规则与任何接口方法或属性的实现规则基本相同。
在类中实现接口事件
在类中声明事件,然后在适当的位置调用该事件。
public
interface
IDrawingObject
{
event EventHandler ShapeChanged;
}
public class MyEventArgs : EventArgs {…}
public class Shape : IDrawingObject
{
event EventHandler ShapeChanged;
void ChangeShape()
{
// Do something before the event…
OnShapeChanged(new MyEventsArgs(…));
// or do something after the event.
}
protected virtual void OnShapeChanged(MyEventArgs e)
{
if(ShapeChanged != null)
{
ShapeChanged(this, e);
}
}
}
{
event EventHandler ShapeChanged;
}
public class MyEventArgs : EventArgs {…}
public class Shape : IDrawingObject
{
event EventHandler ShapeChanged;
void ChangeShape()
{
// Do something before the event…
OnShapeChanged(new MyEventsArgs(…));
// or do something after the event.
}
protected virtual void OnShapeChanged(MyEventArgs e)
{
if(ShapeChanged != null)
{
ShapeChanged(this, e);
}
}
}
示例
下面的示例演示如何处理以下的不常见情况:您的类是从两个以上的接口继承的,每个接口都含有同名事件。在这种情况下,您至少要为其中一个事件提供显式接口实现。为事件编写显式接口实现时,必须编写add和remove事件访问器。这两个事件访问器通常由编译器提供,但在这种情况下编译器不能提供。
您可以提供自己的访问器,以便指定这两个事件是由您的类中的同一事件表示,还是由不同事件表示。例如,根据接口规范,如果事件应在不同时间引发,则可以将每个事件与类中的一个单独实现关联。在下面的示例中,订户将形状引用强制转换为IShape或IDrawingObject,从而确定自己将会接受哪个OnDraw事件。
namespace
WrapTwoInterfaceEvents
{
using System;
public interface IDrawingObject{
//Raise this event before drawing
//the object
event EventHandler OnDraw;
}
public interface IShape{
//Raise this event after drawing
//the shape.
event EventHandler OnDraw;
}
//Base class event publisher inherits two
//interfaces, each with an OnDraw event
public class Shape : IDrawingObject, IShape{
//Create an event for each interface event
event EventHandler PreDrawEvent;
event EventHandler PostDrawEvent;
//Explicit interface implementation required.
//Associate IDrawingObject's event with
//PreDrawEvent
event EventHandler IDrawingObject.OnDraw{
add{
PreDrawEvent += value;
}
remove{
PreDrawEvent -= value;
}
}
//Explicit interface implementation required.
//Associate IShape's event with
//PostDrawEvent
event EventHandler IShape.OnDraw{
add{
PostDrawEvent += value;
}
remove{
PostDrawEvent -= value;
}
}
//For the sake of simplicity this one method
//implements both interfaces.
public void Draw(){
//Raise IDrawingObject's event before the object is drawn.
EventHandler handler = PreDrawEvent;
if (handler != null){
handler(this,new EventArgs());
}
Console.WriteLine("Drawing a shape.");
//RaiseIShape's event after the object is drawn.
handler = PostDrawEvent;
if (handler != null){
handler(this,new EventArgs());
}
}
}
public class Subscriber1{
//References the shape object as an IDrawingObject
public Subscriber1(Shape shape){
IDrawingObject d = (IDrawingObject)shape;
d.OnDraw += new EventHandler(d_OnDraw);
}
void d_OnDraw(object sender,EventArgs e){
Console.WriteLine("Sub1 receives the IDrawingObject event.");
}
}
//References the shape object as an IShape
public class Subscriber2{
public Subscriber2(Shape shape){
IShape d = (IShape)shape;
d.OnDraw += new EventHandler(d_OnDraw);
}
void d_OnDraw(object sender,EventArgs e){
Console.WriteLine("Sub2 receives the IShape event.");
}
}
public class Program2{
static void Main(string[] args){
Shape shape = new Shape();
Subscriber1 sub = new Subscriber1(shape);
Subscriber2 sub2 = new Subscriber2(shape);
shape.Draw();
Console.WriteLine("Press Enter to close this window.");
Console.ReadLine();
}
}
}
using System;
public interface IDrawingObject{
//Raise this event before drawing
//the object
event EventHandler OnDraw;
}
public interface IShape{
//Raise this event after drawing
//the shape.
event EventHandler OnDraw;
}
//Base class event publisher inherits two
//interfaces, each with an OnDraw event
public class Shape : IDrawingObject, IShape{
//Create an event for each interface event
event EventHandler PreDrawEvent;
event EventHandler PostDrawEvent;
//Explicit interface implementation required.
//Associate IDrawingObject's event with
//PreDrawEvent
event EventHandler IDrawingObject.OnDraw{
add{
PreDrawEvent += value;
}
remove{
PreDrawEvent -= value;
}
}
//Explicit interface implementation required.
//Associate IShape's event with
//PostDrawEvent
event EventHandler IShape.OnDraw{
add{
PostDrawEvent += value;
}
remove{
PostDrawEvent -= value;
}
}
//For the sake of simplicity this one method
//implements both interfaces.
public void Draw(){
//Raise IDrawingObject's event before the object is drawn.
EventHandler handler = PreDrawEvent;
if (handler != null){
handler(this,new EventArgs());
}
Console.WriteLine("Drawing a shape.");
//RaiseIShape's event after the object is drawn.
handler = PostDrawEvent;
if (handler != null){
handler(this,new EventArgs());
}
}
}
public class Subscriber1{
//References the shape object as an IDrawingObject
public Subscriber1(Shape shape){
IDrawingObject d = (IDrawingObject)shape;
d.OnDraw += new EventHandler(d_OnDraw);
}
void d_OnDraw(object sender,EventArgs e){
Console.WriteLine("Sub1 receives the IDrawingObject event.");
}
}
//References the shape object as an IShape
public class Subscriber2{
public Subscriber2(Shape shape){
IShape d = (IShape)shape;
d.OnDraw += new EventHandler(d_OnDraw);
}
void d_OnDraw(object sender,EventArgs e){
Console.WriteLine("Sub2 receives the IShape event.");
}
}
public class Program2{
static void Main(string[] args){
Shape shape = new Shape();
Subscriber1 sub = new Subscriber1(shape);
Subscriber2 sub2 = new Subscriber2(shape);
shape.Draw();
Console.WriteLine("Press Enter to close this window.");
Console.ReadLine();
}
}
}
如何:使用字典存储事件实例
accessor-declarations的一种用法是公开大量的事件但不为每个事件分配字段,而是使用字典来存储这些事件实例。这只有在具有非常多的事件、但您预计大部分事件都不会实现时才有用。
示例
public
delegate
void
EventHandler1(
int
i);
public delegate void EventHandler2( string s);
public class PropertyEventsSample {
private System.Collections.Generic.Dictionary<string,System.Delegate> eventTable;
public PropertyEventsSample(){
eventTable = new System.Collections.Generic.Dictionary<string,System.Delegate>();
eventTable.Add("Event1",null);
eventTable.Add("Event2",null);
}
public event EventHandler1 Event1{
add{
eventTable["Event1"] = (EventHandler1)eventTable["Event1"] + value;
}
remove{
eventTable["Event1"] = (EventHandler1)eventTable["Event1"] - value;
}
}
public event EventHandler2 Event2{
add{
eventTable["Event2"] = (EventHandler2)eventTable["Event2"] + value;
}
remove{
eventTable["Event2"] = (EventHandler2)eventTable["Event2"] - value;
}
}
internal void RaiseEvent1(int i){
EventHandler1 handler1;
if (null != (handler1 = (EventHandler1)eventTable["Event1"])){
handler1(i);
}
}
internal void RaiseEvent2(string s){
EventHandler2 handler2;
if (null != (handler2 = (EventHandler2)eventTable["Event2"])){
handler2(s);
}
}
}
public class TestClass2 {
public static void Delegate1Method(int i){
System.Console.WriteLine(i);
}
public static void Delegate2Method(string s){
System.Console.WriteLine(s);
}
static void Main(){
PropertyEventsSample p = new PropertyEventsSample();
p.Event1 += new EventHandler1(TestClass.Delegate1Method);
p.Event1 += new EventHandler1(TestClass.Delegate1Method);
p.Event1 -= new EventHandler1(TestClass.Delegate1Method);
p.RaiseEvent1(2);
p.Event2 += new EventHandler2(TestClass.Delegate2Method);
p.Event2 += new EventHandler2(TestClass.Delegate2Method);
p.Event2 -= new EventHandler2(TestClass.Delegate2Method);
p.RaiseEvent2("TestString");
}
}
public delegate void EventHandler2( string s);
public class PropertyEventsSample {
private System.Collections.Generic.Dictionary<string,System.Delegate> eventTable;
public PropertyEventsSample(){
eventTable = new System.Collections.Generic.Dictionary<string,System.Delegate>();
eventTable.Add("Event1",null);
eventTable.Add("Event2",null);
}
public event EventHandler1 Event1{
add{
eventTable["Event1"] = (EventHandler1)eventTable["Event1"] + value;
}
remove{
eventTable["Event1"] = (EventHandler1)eventTable["Event1"] - value;
}
}
public event EventHandler2 Event2{
add{
eventTable["Event2"] = (EventHandler2)eventTable["Event2"] + value;
}
remove{
eventTable["Event2"] = (EventHandler2)eventTable["Event2"] - value;
}
}
internal void RaiseEvent1(int i){
EventHandler1 handler1;
if (null != (handler1 = (EventHandler1)eventTable["Event1"])){
handler1(i);
}
}
internal void RaiseEvent2(string s){
EventHandler2 handler2;
if (null != (handler2 = (EventHandler2)eventTable["Event2"])){
handler2(s);
}
}
}
public class TestClass2 {
public static void Delegate1Method(int i){
System.Console.WriteLine(i);
}
public static void Delegate2Method(string s){
System.Console.WriteLine(s);
}
static void Main(){
PropertyEventsSample p = new PropertyEventsSample();
p.Event1 += new EventHandler1(TestClass.Delegate1Method);
p.Event1 += new EventHandler1(TestClass.Delegate1Method);
p.Event1 -= new EventHandler1(TestClass.Delegate1Method);
p.RaiseEvent1(2);
p.Event2 += new EventHandler2(TestClass.Delegate2Method);
p.Event2 += new EventHandler2(TestClass.Delegate2Method);
p.Event2 -= new EventHandler2(TestClass.Delegate2Method);
p.RaiseEvent2("TestString");
}
}