C#事件(event)的理解

这篇具有很好参考价值的文章主要介绍了C#事件(event)的理解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、多播委托的应用--观察者模式

遇到一个开发的问题?
面试者:以面向对象的思想实现一下的场景:
猫:Miao一声,紧接着引发了一系列的行为~
Miao:引发了一系列的动作;

从代码层面来说:代码这样写好吗?

  1. 猫职责不单一(猫就是猫,他的行为只有Miao一声)
  2. 依赖太重,依赖了很多的普通类; 被依赖的类如果修改,可能会引发这个猫也要修改;---代码不稳定;
  3. 如果要控制顺序---也要修改代码; 有新需求,必须要修改历史代码---开闭原则;

从传统的方式去考虑的话,我们可能会写出来这个如此这样的代码

class Dog
{
    public void Bark()
    {
        Console.WriteLine("Dog Bark!");

    }
}

class Fox
{
    public void Eat()
    {
        Console.WriteLine("Fox Eat!");

    }
    
}

class Cat
{
    public void Miao()
    {
        new Fox().Eat();
        new Dog().Bark();

        Console.WriteLine("Cat Miao!");
    }
}

从代码层面来说:代码这样写好吗?

  1. 猫职责不单一(猫就是猫,他的行为只有Miao一声)
  2. 依赖太重,依赖了很多的普通类; 被依赖的类如果修改,可能会引发这个猫也要修改;---代码不稳定;
  3. 如果要控制顺序---也要修改代码; 有新需求,必须要修改历史代码---开闭原则;

如何解决呢? 第一个问题:让猫的职责单一, 后续触发的行为,猫Miao一声之后,只负责触发; 触发的是一堆的行为;
请问:如果要希望在触发一个行为后,能够执行多个行为,执行一系列的行为?? 怎么办?-------多播委托;

核心:把依赖的东西转移到上端,保证当前类的稳定; ----可以做到解耦
二者实现本质:是相通的; 都是类似于一个盒子, OOP: 盒子中装对象 委托:盒子装方法;

通过OOP 继承实现的ObServer
IObject.cs

 public interface IObject
 {
     public void DoAction();

 }

Baby.cs

public class Baby:IObject
{
   public void Cry()
    {
        Console.WriteLine("Baby Cry");
    }

    public void DoAction()
    {
        Cry();
    }
}

Brother.cs

 public class Brother:IObject
 {
     public void Turn()
     {
         Console.WriteLine("Brother Turn");
     }

     public void DoAction()
     {
         Turn();
     }
 }

Dog.cs

 public class Dog:IObject
 {
     public void Wang()
     {
         Console.WriteLine("Dog Wang");
     }

     public void DoAction()
     {
         Wang();
     }
 }

Father.cs

 public class Father:IObject
 {
     public void Roar()
     {
         Console.WriteLine("Father Roar");
     }

     public void DoAction()
     {
         Roar();
     }
 }

Mother.cs

 public class Mother:IObject
 {
     public void Wispher()
     {
         Console.WriteLine("Mother Wispher");
     }

     public void DoAction()
     {
         Wispher();
     }
 }

Mouse.cs

 public class Mouse:IObject
 {
     public void Run()
     {
         Console.WriteLine("Mouse Run");
     }
     public void DoAction()
     {
         Run();
     }
 }

Neighbor.cs

public class Neighbor:IObject
{
    public void Awake()
    {
        Console.WriteLine("Neighbor Awake");
    }
    public void DoAction()
    {
        Awake();
    }

}

Stealer.cs

public class Stealer:IObject
{
    public void Hide()
    {
        Console.WriteLine("Stealer Hide");
    }
    public void DoAction()
    {
        Hide();
    }
}

Cat.cs

public class Cat
{  
    public List<IObject> ObserList=new List<IObject>(); 
    public void MiaoObserver()
    {
        Console.WriteLine($"{this.GetType().Name} MiaoObserver========");
        foreach ( IObject item in ObserList )
        { 
            item.DoAction();
        } 
    }
}

Progarm.cs

Console.WriteLine("=========================================");
Console.WriteLine("=========================================");
{
    Cat cat = new Cat();
    cat.objects.Add(new Baby());
    cat.objects.Add(new Mother());
    cat.objects.Add(new Dog());
    cat.objects.Add(new Mouse());
    cat.objects.Add(new Father());
    cat.objects.Add(new Neighbor());
    cat.objects.Add(new Stealer());
    cat.objects.Add(new Brother());
    cat.MiaoObserver();
}
Console.WriteLine("=========================================");
Console.WriteLine("=========================================");

通过委托实现
cat.cs

public Action? MiaoDelegate;

public void MiaoDelegateObserver()
{
    Console.WriteLine($"{this.GetType().Name} MiaoDelegateObserver========");
    if (MiaoDelegate != null)
    {
        MiaoDelegate();
    }
}

program.cs

Console.WriteLine("=========================================");
Console.WriteLine("=========================================");
{
    Cat cat = new Cat();
    cat.MiaoDelegate += new Baby().Cry;
    cat.MiaoDelegate += new Mother().Wispher;
    cat.MiaoDelegate += new Dog().Wang;
    cat.MiaoDelegate += new Mouse().Run;
    cat.MiaoDelegate += new Father().Roar;
    cat.MiaoDelegate += new Neighbor().Awake;
    cat.MiaoDelegate += new Stealer().Hide;
    cat.MiaoDelegate += new Brother().Turn;
    //cat.ActionHander -= new Baby().Cry;
    //  cat.ActionHander.Invoke();// 委托可以在定义委托所在类的外部去执行;
    cat.MiaoDelegateObserver();
}

Console.WriteLine("=========================================");
Console.WriteLine("=========================================");

通过事件实现

cat.cs

public event Action ActionHanderEvent;   
public void MiaoEvent()
{
    Console.WriteLine($"{this.GetType().Name} MiaoEvent========");
    ActionHanderEvent.Invoke();   //这个行为要一定是执行 MiaoEvent方法的时候才触发的;
} 

program.cs

 Console.WriteLine("事件的应用:============================");
 {
     Cat cat = new Cat();
     cat.ActionHanderEvent += new Baby().Cry;
     cat.ActionHanderEvent += new Mother().Wispher;
     cat.ActionHanderEvent += new Dog().Wang;
     cat.ActionHanderEvent += new Mouse().Run;
     cat.ActionHanderEvent += new Father().Roar;
     cat.ActionHanderEvent += new Neighbor().Awake;
     cat.ActionHanderEvent += new Stealer().Hide; 
     // cat.ActionHanderEvent -= new Baby().Cry;
     //cat.ActionHanderEvent.Invoke();
     cat.MiaoEvent ();
 }

什么是事件,其实就是委托的实例+关键字; 事件是一个特殊的委托;
委托和事件有什么区别?
1 多个了关键字
2 事件的权限控制会更加严格--事件的执行,只能,必须在声明这个事件所在的类的内部才能执行;
已经有了委托,为什么还要事件呢?----在系统框架设计中,需要这样的权限控制;

已经有了委托,为什么还要事件呢?----在系统框架设计中,需要这样的权限控制;
使用winform程序来做示范

C#事件(event)的理解

登录
思路:按钮点击会触发这个方法,如果是通过事件来完成,必然会有一个地方定义得有事件,还要把这个方法给注册到事件中去;
执行的逻辑:在按钮初始化的时候,把按钮中的Click 指向一个方法btnLogin_Click;
运行起来: 鼠标点击按钮----操作系统可以捕捉到鼠标的信号,通过句柄判断,确定是哪个程序,通过程序中句柄判断是按个一个组件(按钮),可以获取到按钮的实例; 得到的是登录按钮; 鼠标单机左键信号,按钮

委托和事件的功能差不多---按钮的点击后触发的行为,为什么用事件而不用委托?????
就是为了要管控这个按钮,只能在特定的情况下去执行;

如果用委托:委托就可以在外部去执行;
点击登录,触发登录的方法----必须是点击登录后触发 所以只能用事件而不能用委托
点击注册,触发注册的方法----必须是点击注册后触发 所以只能用事件而不能用委托
不能通过任何其他别的渠道来触发这个方法
如果我使用委托:尽管一在点击了按钮之后,可以触发对应的行为,但是委托没有权限的限制,就可以在外部执行这个委托----不允许的;保证动作触发的来源一定是来自于哪里;

委托和事件的相通性:
二者功能差不多,观察者;在程序中,除了保证代码的问题;
其他场景
三个按钮---鼠标指向---变颜色(按钮的行为); 所有的按钮都有这个行为; 而单单只有登录和注册--点击后可以触发对应的方法;因为给这两个按钮的Click事件注册了行为;

在系统的框架中,如果有一段逻辑的执行; 其中有一些通用的逻辑(三个按钮都有执向变颜色),还有一些个性化的逻辑,每个按钮点击后可能需要执行不同的逻辑; 可以通过事件来进行注册;

价值: 可以把通用的逻辑封装
把可变的逻辑通过事件注册

执行来了,通用逻辑(统一的代码执行)-----可变的逻辑(各自执行各自的~·) 程序可以更加灵活~~ Web--- ASP.NET MVC管道处理模型~~

2.定义事件+实现发布订阅

1.朝夕要发布新课程,嵌入式和C++ Qt (都是Richard老师给大家上课)
2.很多小伙伴们很期待,很关注
3.如果课程发布,根据需求报名学习
文章来源地址https://www.toymoban.com/news/detail-837928.html

 public class EventStandard
 { 
     private static PublicCourse publicCourse1 = new PublicCourse()
     {
         Id = 222,
         Name = "Qt和C++",
     }; 
     private static PublicCourse publicCourse2 = new PublicCourse()
     {
         Id = 222,
         Name = "嵌入式开发",
     };
      
     /// <summary>
     /// 发布课程
     /// </summary>
     public static void Show()
     {
         publicCourse1.PublicShow();// 只关注发布,发布后,会有后续的行为
         publicCourse2.PublicShow();
     }

     /// <summary>
     /// 初始化订阅者和发布者之间的关系( 订阅中心 )
     /// </summary>
     public static void Init()
     {
         StudentUser user1 = new StudentUser()
         {
             Id = 123,
             Name = "夕林吹雪"
         };
         publicCourse1.Publish += user1.Buy;
         publicCourse2.Publish += user1.Buy;
      
         StudentUser user2 = new StudentUser()
         {
             Id = 123,
             Name = "张三"
         };
         publicCourse1.Publish += user2.Buy;
         publicCourse2.Publish += user2.Buy;


         StudentUser user3 = new StudentUser()
         {
             Id = 123,
             Name = "李四"
         };
         publicCourse1.Publish += user3.Buy;
         publicCourse2.Publish += user3.Buy;
     }

 }

 /// <summary>
 /// 发布者
 /// 发布后,就会有后续的逻辑---具体是什么,不知道
 /// </summary>
 public class PublicCourse
 {
     public int Id { get; set; }

     public string Name { get; set; }

     public void PublicShow()
     {
         Console.WriteLine("朝夕新课程发布: Qt+C++  嵌入式开发~~~");
         //会有很多的人关注
         //会有很多的后续动作执行, 有人咨询,有人报名,有人体验课程~

         Publish.Invoke(this, new CourseInfo()
         {
             Id=345,
             Title="Qt和 C++"
         });

     }
     public event EventHandler Publish;
 }


 /// <summary>
 /// 订阅者(订户):
 /// 订阅消息,消息出现,就会触发行为;
 /// </summary>
 public class StudentUser
 {
     public int Id { get; set; }
     public string Name { get; set; }

     public void Buy(object? sender, EventArgs e)
     {
         PublicCourse  course= (PublicCourse)(sender);
         Console.WriteLine($"朝夕有新的课程发布,可称为{course.Name}");
         Console.WriteLine($"用户:{Name}先了解下,考虑考虑");
         Console.WriteLine($"可以购买学习~~");
     }

 }

 /// <summary>
 /// 扩展参数
 /// </summary>
 public class CourseInfo : EventArgs
 {
     public int Id { get; set; }
     public string Title { get; set; }
     public string Description { get; set; }
     public string TeacherWechatNum { get; set; }
 }

到了这里,关于C#事件(event)的理解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C#事件(event)的理解

    遇到一个开发的问题? 面试者:以面向对象的思想实现一下的场景: 猫:Miao一声,紧接着引发了一系列的行为~ Miao:引发了一系列的动作; 从代码层面来说:代码这样写好吗? 猫职责不单一(猫就是猫,他的行为只有Miao一声) 依赖太重,依赖了很多的普通类; 被依赖的类

    2024年03月09日
    浏览(47)
  • C# 深入理解事件(event)机制

    目录 一,引言 二,事件的定义和用法 2.1 同步事件执行  2.2 异步事件执行 2.3 等待异步事件完成 2.4 捕获异常处理中的异常 三,事件的综合案例 3.1 需求:汽车出停车场时收费,开闸放行 都知道事件的本质是一个多播委托(MulticastDelegate),但对于事件的机制和用法一直懵懵

    2024年02月16日
    浏览(32)
  • Unity 事件监听与广播(高度解耦合,观察者模式)

    使用观察者模式降低模块间的耦合性 通过C# 的 Dictionary 存放事件码和事件的委托 添加事件: 判断字典是否有该事件码,没有添加 判断当前委托类型与添加的事件码的类型是否一致 最后订阅该事件 移除事件: 先判断事件码是否存在 取消订阅 最后判断事件码是否为空,是

    2024年02月12日
    浏览(34)
  • [Unity] No.3 EventManager事件管理 与 观察者模式

    前文讲到了InputManager,在其后需要一个事件的管理者用于调度任务的执行,包括: ①查看发生了什么事; ②出事后看看都需要通知谁干什么事; 以上两个内容就对应了EventManager中关键的 监听 和 回调 ,而在讲EventManager之前还需要知道,它是符合观察者这一模式的。 此处不

    2024年02月08日
    浏览(35)
  • 从源码Debug深入spring事件机制,基于观察者模式仿写spring事件监听骨架

    定义一个事件 定义两个listener 注入spring容器里的ApplicationEventPublisher对象,发布事件 从 eventPublisher.publishEvent(new MyEvent(\\\"xxx\\\")); 进去很容易就能找到,可以发现 SimpleApplicationEventMulticaster这个事件发布对象持有所有listenter对象及MyEvent对象 , 事件发布过程其实就是遍历拿到每个li

    2024年02月12日
    浏览(32)
  • 【C++ 观察者模式 思想理解】C++中的观察者模式:松耦合设计与动态交互的艺术,合理使用智能指针观察者

    在进入技术细节之前,理解观察者模式(Observer Pattern)的基本概念和它在现代编程中的重要性是至关重要的。 观察者模式是一种设计模式,它定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。在C++中,这个

    2024年01月24日
    浏览(44)
  • C#设计模式之---观察者模式

    观察者模式(Observer Pattern)是一种对象行为模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。在观察者模式中,主体是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的

    2024年02月16日
    浏览(25)
  • C#设计模式之观察者模式

    观察者(Observer)模式也称发布-订阅(Publish-Subscribe)模式,定义了对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 观察者模式的图解如下所示: Subject(目标): 目标知道它的观察者。可以有任意多个观察者观察

    2024年02月03日
    浏览(34)
  • 深入理解设计模式-行为型之观察者

    观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种 一对多的依赖关系 ,让 多个观察者对象 同时监听一个 主题对象 ,当 主题对象 发生 变化 时,所有依赖于它的 观察者 对象都会得到 通知并更新。 在观察者模式中,有两个主要角色: Subject(主题):维护

    2024年02月12日
    浏览(33)
  • c#设计模式-行为型模式 之 观察者模式

    又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者 对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自 动更新自己。 在观察者模式中有如下角色: Subject:抽象主题(抽象被观察者)

    2024年02月14日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包