对象或者类可以向其他对象或者通过事件发送该对象相关的事情,发送方是发行者,接收或者处理方是事件的订阅者。
事件具有以下属性(微软官方原话):
1、发行者确定何时引发事件;订户确定对事件作出何种响应。
2、一个事件可以有多个订户。 订户可以处理来自多个发行者的多个事件。
3、没有订户的事件永远也不会引发。
4、 事件通常用于表示用户操作,例如单击按钮或图形用户界面中的菜单选项。
5、当事件具有多个订户时,引发该事件时会同步调用事件处理程序。 若要异步调用事件,请参阅 Calling Synchronous Methods Asynchronously。
6、在 .NET Framework 类库中,事件基于 EventHandler 委托和 EventArgs 基类
声明事件(Event)
首先必须声明该事件的委托类型。
public delegate void LogHandler(string msg);
然后,使用 event 关键字声明事件。
// 基于上面的委托定义事件
public event LogHandler LogEvent;
事件订阅
使用加法赋值运算符 (+=) 来为事件附加事件处理程序
以下四种方式都是正确的:
log.LogEvent += new Log.LogHandler(Log_LogEvent);
log.LogEvent += Log_LogEvent;
log.LogEvent += delegate (string msg){};
log.LogEvent += (msg) =>{};
事件取消
使用减法赋值运算符 (-=) 取消订阅事件,或者赋值null ,取消所有订阅的事件
示例代码如下:
public class Log
{
public delegate void LogHandler(string msg);
public event LogHandler LogEvent;
public void EventTest(string str)
{
if (LogEvent != null)
{
LogEvent.Invoke(str);
}
}
}
class Program
{
static void Main(string[] args)
{
Log log = new Log();
log.LogEvent += new Log.LogHandler(Log_LogEvent);
//C# 2.0新语法
log.LogEvent += Log_LogEvent;
//匿名委托
log.LogEvent += delegate (string msg)
{
Console.WriteLine("匿名委托 receive:{0}",msg);
};
//lambda 表达式
log.LogEvent += (msg) =>
{
Console.WriteLine(" lambda 表达式 receive:{0}", msg);
};
log.EventTest("我这着火了");
Console.ReadKey();
}
private static void Log_LogEvent(string msg)
{
Console.WriteLine(" receive msg: {0}",msg);
}
}
结果 如下:
receive msg: 我这着火了
receive msg: 我这着火了
匿名委托 receive:我这着火了
下边的是微软官方文档:
https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/events/index