在定义委托时,前面加上event关键字,可以保证该委托不能在外部被随意触发,两者异同:
注册 | 注销 | 内部触发 | 外部触发 | |
delegate | += | -= | Invoke | Invoke |
event delegate | += | -= | Invoke | 不允许 |
所以,event关键字有助于提高类的封装性,物理隔绝代码耦合,迫使类设计更追求高内聚。
定义一个显示消息的event并包装
public event EventHandler evt_log_handle;
protected virtual void On_evt_log_handle(object obj, EventArgs e)
{
if (this.evt_log_handle != null)
this.evt_log_handle(obj, e);
}
在外部触发:
On_evt_log_handle("日志", null);
在其他类中,可以注册这个事件
m_project.evt_log_handle += m_process_evt_log_handle; m_project为定义event的类的实例
定义事件实现的代码
void m_process_evt_log_handle(object sender, EventArgs e)
{
string sLog = sender as string;
...
}
控制台输入'a'累加到上限实现事件的示例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
Counter c = new Counter(new Random().Next(10));
c.ThresholdReached += c_ThresholdReached; //注册事件
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e) //事件实现
{
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached);
Environment.Exit(0);
}
}
class Counter
{
private int threshold;
private int total;
public Counter(int passedThreshold)
{
threshold = passedThreshold;
}
public void Add(int x)
{
total += x;
if (total >= threshold)
{
ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
args.Threshold = threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
}
public event EventHandler<ThresholdReachedEventArgs> ThresholdReached;
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
if (this.ThresholdReached != null)
{
this.ThresholdReached(null, e);
}
}
}
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
}