一 事件

1 抛砖引玉·案例
- 订阅和发布机制
- 比如说,我要下楼去吃饭,正常情况下我会问一下室友是否需要我带饭。我每个人问一遍的情况,很浪费时间。
- 现在,我提前放好纸和笔,要求别人列好需要我帮忙的事情,我到时候直接拿着单子下楼。这就是订阅和发布机制。
1.1工具人下楼案例
1.1.1 ToolMan.cs
public delegate void DownStairDelegate();
public class ToolMan
{
public string Name { get; set; }
public DownStairDelegate DoList = null;
public ToolMan(string name)
{
Name = name;
}
public void DownStair()
{
Console.WriteLine("工具人"+Name+"下楼了");
if (DoList != null)
{
DoList();
}
}
}
1.1.2 LazyMan.cs
using System;
namespace test06
{
public class LazyMan
{
public string Name { get; set; }
public LazyMan(string name)
{
Name = name;
}
public void TakeFood()
{
Console.WriteLine("给"+Name+"外卖");
}
public void TakePackage()
{
Console.WriteLine("给"+Name+"快递");
}
}
}
1.1.3 Program.cs
using System;
namespace test06
{
internal class Program
{
public static void Main(string[] args)
{
var toolMan = new ToolMan("小明");
var lazyMan = new LazyMan("小李");
var lazyMan1 = new LazyMan("小王");
var lazyMan2 = new LazyMan("小空");
toolMan.DoList += lazyMan.TakeFood;
toolMan.DoList += lazyMan1.TakePackage;
toolMan.DoList += lazyMan2.TakeFood;
toolMan.DoList();
Console.WriteLine("===========");
toolMan.DoList -= lazyMan2.TakeFood;
toolMan.DoList();
Console.WriteLine("===========");
toolMan.DoList = lazyMan2.TakeFood;
toolMan.DoList();
}
}
}
1.1.4 测试结果

1.1.5 升级到事件

internal class Program
{
public static void Main(string[] args)
{
var toolMan = new ToolMan("小明");
var lazyMan = new LazyMan("小李");
var lazyMan1 = new LazyMan("小王");
var lazyMan2 = new LazyMan("小空");
toolMan.DoList += lazyMan.TakeFood;
toolMan.DoList += lazyMan1.TakePackage;
toolMan.DoList += lazyMan2.TakeFood;
Console.WriteLine("===========");
toolMan.DoList -= lazyMan2.TakeFood;
Console.WriteLine("===========");
toolMan.DownStair();
}
}

二 委托和事件的区别和联系

- 事件是一种特殊的委托,或者说是受限制的委托,是委托一种特殊应用,只能施加+-,-二操作符。二者本质上是一个东西。
- event ActionHandler Tick;//编译成创建一个私有的委托示例,和施加在其上的add,remove方法.
- event只允许用add,remove方法来操作,这导致了它不允许在类的外部被直接触发,只能在类的内部适合的时机触发。委托可以在外部被触发,但是别这么用。
- 使用中,委托常用来表达回调,事件表达外发的接口。
- 委托和事件支持静态方法和成员方法,delegate(void* pthis,f_ptr)支持静态返回方法时,pthis传null.支持成员方法时pthis传被通知的对象.
- 委托对象里的三个重要字段是,pthis、f_ptr、pnext,也就是被通知对象引用,函数指针\地址,委托链表的下一个委托节点。