如何:实现接口事件
接口可声明事件。下面的示例演示如何在类中实现接口事件。接口事件的实现规则与任何接口方法或属性的实现规则基本相同。
在类中实现接口事件
在类中声明事件,然后在适当的位置调用该事件。
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);
}
}
}

示例
下面的示例演示如何处理以下的不常见情况:您的类是从两个以上的接口继承的,每个接口都含有同名事件。在这种情况下,您至少要为其中一个事件提供显式接口实现。为事件编写显式接口实现时,必须编写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();
}
}
}

如何:使用字典存储事件实例
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");
}
}
