我们遵循.NET Framework标准事件模式的添加到类和结构中,.NET Framework 类库中的所有事件均基于 EventHandler 委托,定义如下:
public delegate void EventHandler(object sender, EventArgs e);
.NET Framework 2.0 引入了泛型版本的委托 EventHandler<TEventArgs>。 定义如下:
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
尽管定义的类中的事件可基于任何有效委托类型,但一般还是建议使用EventHandler委托,因为这是.NET Framework的标准实现。标准里面主要有三个要素:
1. object sender: 声明事件成员的类。
2. EventArgs e: 所有订阅事件的对象可能关心的数据。
3. delegate void EventHandler(object sender, EventArgs e):事件背后的委托类型
标准实现看起来有点复杂,但是它有更多的好处,首先所有的事件编码规范一致了,有更多的可读性,然后程序也有了更大的灵活性。任何订阅了事件的对象,可以通过object sender参数来访问publisher对象,这是非常方便的。
使用EventHandler来实现事件
首先确定事件需要不需要自定义EventArgs。
1.不需要自定义EventArgs,可以直接声明发布类的事件成员:
public event EventHandler MyCustomEvent;
2.需要自定义EventArgs,先定义CustomEventArgs类型:
public class CustomEventArgs : EventArgs
{
public CustomEventArgs(string s)
{
msg = s;
}
private string msg;
public string Message
{
get { return msg; }
}
}
再自定义委托类型:
public delegate void CustomEventHandler(object sender, CustomEventArgs a);
最后声明发布类的事件成员:
public event CustomEventHandler RaiseCustomEvent;
但是如果使用泛型,可以不用自定义委托,可以直接声明发布类的事件成员:
public event EventHandler<CustomEventArgs> RaiseCustomEvent;
使用自定义 EventArgs 类和 EventHandler<TEventArgs> 作为事件类型来演示之前的步骤:
public class CustomEventArgs : EventArgs
{
public CustomEventArgs(string s)
{
msg = s;
}
private string msg;
public string Message
{
get { return msg; }
}
}
public class Publisher
{
public event EventHandler<CustomEventArgs> MyCustomEvent;
public void DoSomething()
{
// Write some code that does something useful here
// then raise the event. You can also raise an event
// before you execute a block of code.
Console.WriteLine("Publisher will send to subscribers.");
// Make a temporary copy of the event to avoid possibility of
// a race condition if the last subscriber unsubscribes
// immediately after the null check and before the event is raised.
EventHandler<CustomEventArgs> handler = MyCustomEvent;
// Event will be null if there are no subscribers
if (handler != null)
{
// Format the string to send inside the CustomEventArgs parameter
var args = new CustomEventArgs("Did something");
// Use the () operator to raise the event.
handler(this, args);
}
}
}
public class Subscriber
{
private string _id;
public Subscriber(string id, Publisher pub)
{
_id = id;
// Subscribe to the event using C# 2.0 syntax
pub.MyCustomEvent += HandleCustomEvent;
}
// Define what actions to take when the event is raised.
void HandleCustomEvent(object sender, CustomEventArgs e)
{
Console.WriteLine(_id + " received this message: {0}", e.Message);
}
}
Main:
Publisher pub = new Publisher();
Subscriber sub1 = new Subscriber("sub1", pub);
Subscriber sub2 = new Subscriber("sub2", pub);
// Call the method that raises the event.
pub.DoSomething();
通过理解标准,然后我们动手实现,这样可以加深我们的理解。