1. 相同点
事件对象本质就是一个私有的委托对象,以及共有的两个方法add和Remove
2. 不同点
- 委托变量与实现方法的关联允许使用Null ,这样会对之前的关联产生影响
- 事件变量与实现方法的关联不允许使用Null,而且正常的赋值不会影响之前已经存在的关联关系,这样的话,避免用户将对象事件清除,起到保护作用
- 对委托与事件的理解,
委托是 Windows服务器系统
事件则是Windows 普通用户系统
3.一个故事
通过讲述一个 鸿门宴的故事,更好的理解委托与事件的关系
鸿门宴的故事:
1. 冷知识:项羽帐下五员大将:龙且A、季布B、钟离昧C、英布D、虞子期E
在demo中人员名字用ABCDE代表
2. 背景:项羽请刘备吃饭,顺便借机弄死他
3. 于是做了如下安排:
项羽敬酒的时候,
1. 如果项羽用左手敬酒:龙且 过来砍死刘备
2. 如果项羽用右手敬酒:季布 过来砍死刘备
3. 如果项羽直接将酒杯摔在地上:龙且、季布、钟离昧、英布、虞子期一起来砍死刘备
用代码实现上面的过程,
结论就是:
如果用委托的话,可能会出来内奸
因为在委托变量与实现方法进行关联的时候,会影响到已经关联的方法
如果用事件的话,则不会
注:上面的背景纯粹是为了便于理解,杠精请绕道
3.1 用委托实现
#region 主函数调用
XiangYu xiangYu = new XiangYu();
A a = new A(xiangYu);
B b = new B(xiangYu);
C c = new C(xiangYu);
xiangYu.JuShouMethod("左手");
Console.ReadLine();
Console.WriteLine("又宴请了刘邦");
xiangYu.JuShouMethod("右手");
Console.ReadLine();
#endregion
#region 用委托实现
//【1】创建委托
public delegate void JuShou(string hands);
public class XiangYu
{
public void JuShouMethod(string hands)
{
Console.WriteLine($"大王举起了{hands}手!");
//【5】调用委托变量,实现委托
if (JuShowVar != null)
{
JuShowVar(hands);
}
else
{
Console.Beep();
Console.WriteLine("项羽阵营中出现了叛徒!");
}
}
//【3】根据委托定义委托变量
public JuShou JuShowVar;
}
public class A
{
public A(XiangYu xiangYu)
{
//【4】将创建的方法赋值给声明的变量
// 这个关联方法一定要用+=,否则会将之前的关联方法替换掉,这也是不要用委托的原因之一
xiangYu.JuShowVar += new JuShou(this.CutLiubang);
}
//【2】根据委托创建实现方法
private void CutLiubang(string hands)
{
if (hands.Equals("左手"))
{
Console.WriteLine($"我是龙且,大王举起了{hands}手,我要砍死刘邦");
}
}
}
public class B
{
public B(XiangYu xiangYu)
{
//【4】将创建的方法赋值给声明的变量
// 这个关联方法一定要用+=,否则会将之前的关联方法替换掉,这也是不要用委托的原因之一
xiangYu.JuShowVar += this.CutLiubang;
}
private void CutLiubang(string hands)
{
if (hands.Equals("右手"))
{
Console.WriteLine($"我是季布,大王举起了{hands}手,我要砍死刘邦");
}
}
}
public class C
{
public C(XiangYu xiangYu)
{
//【4】将创建的方法赋值给声明的变量
// 这里设置为Null,会将之前的关联全部处理掉
xiangYu.JuShowVar = null;
}
}
#endregion
3.2 用事件实现
#region 主函数调用
XiangYu xiangYu = new XiangYu();
A a = new A(xiangYu);
B b = new B(xiangYu);
C c = new C(xiangYu);
xiangYu.JuShouMethod("左手");
Console.ReadLine();
Console.WriteLine("又宴请了刘邦");
xiangYu.JuShouMethod("右手");
Console.ReadLine();
#endregion
#region 用事件实现
//【1】创建委托
public delegate void JuShou(string hands);
public class XiangYu
{
//【2】创建事件
public event JuShou jushouEvent;
public void JuShouMethod(string hands)
{
Console.WriteLine($"大王举起了{hands}手!");
//【3】激活事件
if (jushouEvent != null)
{
jushouEvent(hands);
}
else
{
Console.Beep();
Console.WriteLine("项羽阵营中出现了叛徒!");
}
}
}
public class A
{
public A(XiangYu xiangYu)
{
//【4】将事件关联方法
// 事件关联方法:事件无法直接从外部赋值,这样的话,避免用户将对象事件清除,起到保护作用
xiangYu.jushouEvent += new JuShou(this.CutLiubang);
//xiangYu.jushouEvent += null; //这样设置会报错
//xiangYu.jushouEvent -= new JuShou(this.CutLiubang);//这样不会影响之前的关联
}
//【5】创建事件响应方法
private void CutLiubang(string hands)
{
if (hands.Equals("左手"))
{
Console.WriteLine($"我是龙且,大王举起了{hands}手,我要砍死刘邦");
}
}
}
public class B
{
public B(XiangYu xiangYu)
{
//【4】将事件关联方法
// 事件关联方法:事件无法直接从外部赋值,这样的话,避免用户将对象事件清除,起到保护作用
xiangYu.jushouEvent += this.CutLiubang;
}
private void CutLiubang(string hands)
{
if (hands.Equals("右手"))
{
Console.WriteLine($"我是季布,大王举起了{hands}手,我要砍死刘邦");
}
}
}
public class C
{
public C(XiangYu xiangYu)
{
//【4】将事件关联方法
// 事件关联方法:事件无法直接从外部赋值,这样的话,避免用户将对象事件清除,起到保护作用
//xiangYu.jushouEvent = null; //这样设置会报错
}
}
#endregion