C#中的事件和委托(原)
2. 在事件通信中,事件发送方类不知道哪个对象或方法将接收到(处理)它引发的事件。所需要的是在源和接收方之间存在一个媒介(或类似指针的机制)。.NET Framework 定义了一个特殊的类型(Delegate),该类型提供函数指针的功能。
3. 委托是可保存对方法的引用的类。与其他的类不同,委托类具有一个签名,并且它只能对与其签名匹配的方法进行引用。这样,委托就等效于一个类型安全函数指针或一个回调。虽然委托具有许多其他的用途,但这里只讨论委托的事件处理功能。一个委托声明足以定义一个委托类。声明提供委托的签名,公共语言运行库提供实现。
4. 只有当事件生成事件数据时才需要自定义事件委托。许多事件,包括一些用户界面事件(例如鼠标单击)在内,都不生成事件数据。在这种情况下,类库中为无数据事件提供的事件委托 System.EventHandler 便足够了。
delegate void EventHandler(object sender, EventArgs e);
5. 事件功能是由三个互相联系的元素提供的:提供事件数据的类、事件委托和引发事件的类。.NET Framework 具有命名与事件相关的类和方法的约定。如果希望您的类引发一个名为 EventName 的事件,您需要以下元素:
包含事件数据的类,名为 EventNameEventArgs。该类必须从 System.EventArgs 导出。
事件的委托,名为 EventNameEventHandler。
引发事件的类。该类必须提供事件声明 (EventName) 和引发事件 (OnEventName) 的方法。
6. .NET Framework 类库或第三方类库中可能已经定义了事件数据类和事件委托类。在这种情况下,您就不需要定义这些类了。例如,如果您的事件不使用自定义数据,可以使用 System.EventArgs 作为事件数据并使用 System.EventHandler 作为委托。
clock.Alarm += new AlarmEventHandler(w.AlarmRang);
若要取消订阅事件,接收器可以使用减法赋值运算符 (-=) 从源对象的事件中移除事件处理程序的委托。
namespace testEvent
{
public delegate void AlarmEventHandler(object sender, EventArgs e);
public class Clock
{
public event AlarmEventHandler Alarm;
// The protected OnAlarm method raises the event by invoking
// the delegates. The sender is always this, the current instance
// of the class.
//
protected virtual void OnAlarm(EventArgs e)
{
if (Alarm != null) {
// Invokes the delegates.
Alarm( this, e);
}
}
internal void Start()
{
OnAlarm(EventArgs.Empty );
}
}
public class WakeMeUp
{
public void AlarmRang( object sender, EventArgs e) {
System. Console.WriteLine("Event has been invoked!");
}
}
class Program
{
static void Main(string[] args)
{
// Instantiates the event receiver.
WakeMeUp w = new WakeMeUp ();
// Instantiates the event source.
Clock clock = new Clock();
// Wires the AlarmRang method to the Alarm event.
clock.Alarm += new AlarmEventHandler(w.AlarmRang);
clock.Start();
}
}
}
{
public class AlarmEventArgs : EventArgs
{
public string AlarmText;
public AlarmEventArgs(string alarmText)
{
AlarmText = alarmText;
}
}
public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);
public class Clock
{
public event AlarmEventHandler Alarm;
public string state = "the clock is ringing...";
protected virtual void OnAlarm(AlarmEventArgs e)
{
if (Alarm != null) {
// Invokes the delegates.
Alarm(this, e);
}
}
internal void Start()
{
System .Threading.Thread.Sleep(300);
AlarmEventArgs e = new AlarmEventArgs("Please wake up!" );
OnAlarm(e);
}
}
public class WakeMeUp
{
public void AlarmRang( object sender, AlarmEventArgs e)
{
Console .WriteLine(e.AlarmText);
Console.WriteLine ("The state of clock:");
Console. WriteLine(((Clock)sender).state);
Console .ReadLine();
}
}
class Program
{
......
}
}
参考和延伸阅读(需有VS2005 MSDN)
没有评论:
发表评论