事件
大约 7 分钟约 2208 字
事件
事件和委托的区别
{
Cat cat = new Cat();
//cat.Miao();//不好的玩法--依赖太重;
//1.通过定义委托属性
//2.给委托+=方法--Miao一声之后,要触发的动作
//3.特点;把要执行的动作不放在猫的内部从外面去指定
//4.多播委托+=来完成了一系列动作的转移,把猫Miao一声后的动作转移到上端
//5.去掉了猫对于其他的依赖---提高了猫的稳定性
//6.通过委托实现了观察者模式--观察者模式---把不属于我的动作转移出去---甩锅
Console.WriteLine("************************this is delegate****************************");
{
cat.MiaoAction += new Dog().Wang; //狗叫了
cat.MiaoAction += new Mouse().Run;//老鼠跑了
cat.MiaoAction += new Mother().Wispher;
cat.MiaoAction += new Baby().Cry; // 小孩哭了
//cat.MiaoAction += new Mother().Wispher;
cat.MiaoAction += new Father().Roar;
cat.MiaoAction += new Neighbor().Awake;
cat.MiaoAction += new Stealer().Hide;
//cat.MiaoAction = null;
cat.MiaoDelegate();
cat.MiaoAction();//可以执行
}
//1.复制---粘贴---增加了一个Event关键字
//2.事件--委托和事件有什么联系和区别?
//事件是委托的实例--事件是特殊的委托;
//都可以+=/-=;
//3.既然有了多播委托,为什么又搞个事件呢?
// a.安全--事件是只能在类的内部执行;
// b.就算是你的子列也不能执行当前类中的事件,只能由自己来执行;--反射呢.---可以试试
// c.事件从外面操作,只能有一个+=/-=;
Console.WriteLine("************************this is MiaoEventHanlder****************************");
{
cat.MiaoEventHanlder += new Dog().Wang; //狗叫了
cat.MiaoEventHanlder += new Mouse().Run;//老鼠跑了
cat.MiaoEventHanlder += new Mother().Wispher;
cat.MiaoEventHanlder += new Baby().Cry; // 小孩哭了
cat.MiaoEventHanlder += new Father().Roar;
cat.MiaoEventHanlder += new Neighbor().Awake;
cat.MiaoEventHanlder += new Stealer().Hide;
//cat.MiaoEventHanlde = null;
cat.MiaoEnvent();
//cat.MiaoEventHanlder.Invoke(); //不能执行
}
//Console.Read();
//区别:上面是通过多播委托来了支持---语法层面来支持
//两者从本质上来说是没有什么太大的区别;
//区别:下面是通过面向对象的方法会来完成观察者---程序设计层面来支持
Console.WriteLine("************************this is Obeserver****************************");
{
cat.observerlist.Add(new Dog()); //狗叫了
cat.observerlist.Add(new Mouse());//老鼠跑了
cat.observerlist.Add(new Baby()); // 小孩哭了
cat.observerlist.Add(new Mother());
cat.observerlist.Add(new Father());
cat.observerlist.Add(new Neighbor());
cat.observerlist.Add(new Stealer());
cat.MiaoObsever();
}
}
{
/// <summary>
///猫:
/// Miao:引发了一系列的动作;
/// 从代码层面来说:代码这样写好吗?
///
/// 不好:
/// 1.职责不单一---一个类中包含的职责太多了,除了Miao 一声,依赖于其他的类太多;
/// 2.依赖太重--依赖于Dog、Mouse、....---代码不稳定;Dog、Mouse、....任何一个类的修改,都有可能会影响到这只猫;
/// 3.这完全是面向过程式编程--完全是翻译需求;
///
///
/// 改造:
/// 1.职责单一: 猫--职责:仅仅知识Miao一下;其他的动作,不是猫的动作;
/// 2.猫Miao一声后会引发一些列的动作;应该放出去,不能属于这只猫
/// 3.猫Miao一声后,触发一些列的动作---不能把这一些列的动作放在猫的内部
/// </summary>
public class Cat
{
/// <summary>
///
/// </summary>
//public void Miao()
//{
// Console.WriteLine("{0} Miao", this.GetType().Name);
// new Dog().Wang(); //狗叫了
// new Mouse().Run();//老鼠跑了
// new Baby().Cry(); // 小孩哭了
// new Mother().Wispher();
// new Father().Roar();
// new Neighbor().Awake();
// new Stealer().Hide();
//}
public Action MiaoAction = null;
/// <summary>
/// 这个方法仅仅只是Miao一声
/// 引发的动作---可以放到多播委托中去
/// </summary>
public void MiaoDelegate()
{
Console.WriteLine("{0} MiaoDelegate", this.GetType().Name);
//if (MiaoAction != null)
//{
// MiaoAction.Invoke();
//}
MiaoAction?.Invoke();//?. 如果不为null ,就执行后面的动作
}
//static 常驻内存
public event Action MiaoEventHanlder = null;
/// <summary>
/// 这个方法仅仅只是Miao一声
/// 引发的动作---可以放到多播委托中去
/// </summary>
public void MiaoEnvent()
{
Console.WriteLine("{0} MiaoEnvent", this.GetType().Name);
MiaoEventHanlder?.Invoke();//?. 如果不为null ,就执行后面的动作
}
public List<IObject> observerlist = new List<IObject>();
public void MiaoObsever()
{
Console.WriteLine("{0} MiaoObsever", this.GetType().Name);
if (observerlist.Count>0)
{
//observerlist.ForEach(item => item.DoAction());
foreach (var item in observerlist)
{
item.DoAction();
}
}
}
}
public class ChildCat : Cat
{
public void Show()
{
base.MiaoAction(); //子类中执行父类中共的多播委托--可以执行
//base.MiaoEventHanlder.Invoke();//子类中执行父类的时间--不能执行
}
}
}
事件-观察者模式(发布订阅者模式)的—的几大要素
//关于事件的在Winform中的应用
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 如果点击按钮,就会触发这个方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
}
private void button1_ClickTest(object sender, EventArgs e)
{
}
/// <summary>
/// 注册
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click_1(object sender, EventArgs e)
{
}
private void btnLogin_Click(object sender, EventArgs e)
{
}
//Winform:
//登录按钮:双击--生成了一个方法:运行起来,点击按钮---触发这个方法;
//怎么完成的?
//1.按钮其实是一个Button对象实例:继承Control---Control有一个Click事件---事件( EventHandler(object? sender, EventArgs e))
//2.Form1构造函数函数中有一个InitializeComponent方法;在InitializeComponent方法中初始化Button按钮实例,个Button的实例中的Click事件+=一个动作(button1_Click方法)
//3.点击按钮---触发事件---触发事件就是执行注册事件的方法
//其实是鼠标点击左键,就可以触发;为什么要这样设计呢,为什么一定要使用事件呢?
//1.程序运行----句柄被监听---监听鼠标的点击的动作---触发操作系统---操作系统就要去找这个句柄是在哪个应用程序中---控件---执行这个控件中的事件---触发了方法
//2.在按钮点击触发方法的设计中---有很多相同的逻辑(指向按钮,按钮会变色)+很多不同的业务逻辑;就把不变的业务逻辑封装---代码重用,可变的业务逻辑对外发布一个事件,由外部给事件注册动作;需要执行动作的时候;就把不变的,封装在内部的业务逻辑执行;还执行事件(把外部注册到事件上的动作给执行了);注册事件什么动作,就执行什么动作----可以让不同的场景共用相同的业务逻辑,分贝指定各自不同的业务逻辑;
//3.框架设计的时候,是非常需要这种设计的;----ASP.NET MVC5管道处理模型;---就是通过19大事件来完成的;
}
}
标准事件的定义
{
EventStandard1.Show();
EventStandard2.Show();
//1.初始化发布者和订阅者之间的关系
EventStandard1.Init();
EventStandard1.Show();
}
{
/// <summary>
///
///
///
/// </summary>
public class EventStandard1
{
///发布者的实例---公众号的实例已存在
private static PublicNumber publicNumber = new PublicNumber()
{
Id = 123,
Name = "NET社区"
};
public static void Show()
{
publicNumber.PublishShow();//再公众号发布了一片文章
}
//订阅:关联发布者和订阅者之间的关系 (初始化发布者和订阅者之间的关系)
public static void Init()
{
{
///订阅者的实例
Teacher teacher = new Teacher()
{
Id = 234,
Name = "Richard老师"
};
//订阅者的实例
NETer nETer = new NETer()
{
Id = 345,
Name = "小菜同学"
};
//建立发布者和订阅者之间的关系
publicNumber.Push += teacher.Read;
publicNumber.Push += nETer.AddTeache;
}
}
}
/// <summary>
///
/// 发布者:对完发布事件;当触发一个动作后,触发这个事件
/// </summary>
public class PublicNumber
{
public int Id { get; set; }
public string Name { get; set; }
public void PublishShow()
{
Console.WriteLine("发布了一片关于.NET5的文章。。。包含了环境安装的文档。。。");
Push.Invoke(this, new MessageInfo()
{
Id = 567,
Title = ".NET5的文章。。",
Description = "发布了一片关于.NET5的文章。。。包含了环境安装的文档。。。",
TeacherWechatNum = "MrRichard2020"
});
}
public event EventHandler Push;
}
/// <summary>
/// 订阅者:对发布者发布的事情关注
/// </summary>
public class Teacher
{
//public Teacher(PublicNumber publicNumber)
//{
// publicNumber.Push += this.Read;
//}
public int Id { get; set; }
public string Name { get; set; }
public void Read(object? sender, EventArgs e)
{
MessageInfo info = (MessageInfo)e;
Console.WriteLine("内容干货满满。。。。。");
}
}
/// <summary>
/// 订阅者:对发布者发布的事情关注
/// </summary>
public class NETer
{
public int Id { get; set; }
public string Name { get; set; }
public void AddTeache(object? sender, EventArgs e)
{
MessageInfo info = (MessageInfo)e;
Console.WriteLine("内容很多干货。。。");
Console.WriteLine($"添加了助教老师的微信{info.TeacherWechatNum}。。。去获取更多");
}
}
public class MessageInfo : EventArgs
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string TeacherWechatNum { get; set; }
}
}
{
public class EventStandard2
{
public static void Show()
{
AdvancedClass frameworkClass = new AdvancedClass()
{
Id = 1,
Name = "高级班VIP课程",
Price = 4299
};
//订阅:就是个订户和事件发布者关联起来
frameworkClass.PriceIncrease += new StudentInfo().Buy;
frameworkClass.PriceIncrease += new Tencent().Extension;
frameworkClass.Price = 6299;
}
/// <summary>
/// 订户: 关注事件,事件触发后,自己做出相应的动作
/// </summary>
public class StudentInfo
{
public void Buy(object sender, EventArgs e)
{
AdvancedClass frameworkClass = (AdvancedClass)sender;
AdvancedClassEventArge eventArge = (AdvancedClassEventArge)e;
Console.WriteLine($"this is {frameworkClass.Name}");
Console.WriteLine($"{frameworkClass.Name}之前的价格是{eventArge.OldPrice}");
Console.WriteLine($"{frameworkClass.Name}现在要马上更新的价格是{eventArge.NewPrice}");
Console.WriteLine("果断买了。。。");
Console.WriteLine($"{frameworkClass.Name}现在要马上更新的价格是{eventArge.NewPrice}");
}
}
/// <summary>
/// 订户,关注事件,事件触发之前,做出点动作
/// </summary>
public class Tencent
{
public void Extension(object sender, EventArgs e)
{
AdvancedClass frameworkClass = (AdvancedClass)sender;
AdvancedClassEventArge eventArge = (AdvancedClassEventArge)e;
Console.WriteLine($"this is {frameworkClass.Name}");
Console.WriteLine($"{frameworkClass.Name}之前的价格是{eventArge.OldPrice}");
Console.WriteLine($"{frameworkClass.Name}现在要马上更新的价格是{eventArge.NewPrice}");
Console.WriteLine("马上推广一波。。");
}
}
public class AdvancedClassEventArge : EventArgs
{
public int OldPrice { get; set; }
public int NewPrice { get; set; }
}
/// <summary>
/// 事件的发布者,发布是按并且在满足条件的情况下,触发事件
/// </summary>
public class AdvancedClass
{
public int Id { get; set; }
public string Name { get; set; }
private int _price = 5299;
public int Price
{
get
{
return _price;
}
set
{
if (value > _price)
{
///触发一部分动作
PriceIncrease.Invoke(this, new AdvancedClassEventArge()
{
OldPrice = _price,
NewPrice = value
});
}
_price = value;
}
}
public event EventHandler PriceIncrease;
}
}
}