iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >C#开发中事件与委托机制的示例分析
  • 242
分享到

C#开发中事件与委托机制的示例分析

2023-06-17 13:06:13 242人浏览 泡泡鱼
摘要

这篇文章给大家分享的是有关C#开发中事件与委托机制的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。概述C#中的委托类似于C或c++中的函数指针。使用委托使程序员可以将方法引用封装在委托对象内。然后可以将该

这篇文章给大家分享的是有关C#开发中事件与委托机制的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

概述

C#中的委托类似于C或c++中的函数指针。使用委托使程序员可以将方法引用封装在委托对象内。然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调用哪个方法。与C或C++中的函数指针不同,委托是面向对象,而且是类型安全的。

C#中的“事件”是当对象发生某些事情时,类向该类的客户提供通知的一种方法。事件最常见的用途是用于图形用户界面;通常,表示界面中的控件的类具有一些事件,当用户对控件进行某些操作(如单击某个按钮)时,将通知这些事件。

使用委托来声明事件。委托对象封装一个方法,以便可以匿名调用该方法。事件是类允许客户为其提供方法(事件发生时应调用这些方法)的委托的一种方法。事件发生时,将调用其客户提供给它的委托。

注明:委托是对方法的包装 在不确定要调用什么方法时候而又不能用抽象或者多态实现的时候用委托。

public interface PilotLamp     {    /// <summary>    /// green light    /// </summary>    void TurnOn();     /// <summary>     /// notice     /// </summary>     string Notice     {     get;    set;     }     }

先创建PilotLamp.cs

再创建DelegateEvent.cs:

public delegate void EventHandler();

再创建TrafficLight.cs:

public class TrafficLight : PilotLamp     {     public event EventHandler Notices;    private string notice;    #region GreenLight 成员     public void TurnOn()     {     if (Notices != null)     Notices();     }     public string Notice     {    get    {     return notice;     }    set    {     notice = value;     }     }    #endregion     }

再创建Driver.cs

public class Driver        private string Name;    private PilotLamp greenLight;    public Driver(string name, PilotLamp greenLight)    {    this.Name = name;    this.greenLight = greenLight;    }    public void GoLeft()    {    Console.WriteLine(string.FORMat("{1}司机,{0},请向左开车.", greenLight.Notice, Name));    }    }

再创建Pedestrian.cs:

 public class Pedestrian     {     private string Name;    private PilotLamp greenLight;    public Pedestrian(string name, PilotLamp greenLight)    {     this.Name = name;     this.greenLight = greenLight;     }    public void GoThrough()     {     Console.WriteLine( string.Format("{0}同志,{1},请向前走.", Name, greenLight.Notice));     }     }

***再调用:

 public partial class Run : Form    {    public Run()     {     InitializeComponent();    }    private void btnRun_Click(object sender, EventArgs e)     {    //-------------------------------------    TrafficLight trafficLight = new TrafficLight();     Driver driverOne = new Driver("张三", trafficLight);    Driver driverTwo = new Driver("李四", trafficLight);    Pedestrian pedestrianOne = new Pedestrian("王五", trafficLight);     Pedestrian pedestrianTwo = new Pedestrian("麻六", trafficLight);     trafficLight.Notices += new Observer.EventHandler(driverOne.GoLeft);     trafficLight.Notices += new Observer.EventHandler(driverTwo.GoLeft);     trafficLight.Notices += new Observer.EventHandler(pedestrianOne.GoThrough);    trafficLight.Notices += new Observer.EventHandler(pedestrianTwo.GoThrough);     trafficLight.Notice = "绿灯亮了.";     trafficLight.TurnOn();    //-------------------------------------     }     }

输出时选控制台应用程序如图:

C#开发中事件与委托机制的示例分析

结果如下图:

C#开发中事件与委托机制的示例分析

事件的使用示例:

 namespace DelegateAndEvent     {     class Program     {     static void Main(string[] args)    {    Publishser pub = new Publishser();    OneScriber oneSub = new OneScriber();     TwoScriber twoSub = new TwoScriber();    ThreeScriber threeSub = new ThreeScriber ();     pub.NumberChanged += new GeneralEventHandler(oneSub.OnNumberChanged);     pub.NumberChanged += new GeneralEventHandler(twoSub.OnNumberChanged);     pub.NumberChanged += new GeneralEventHandler(threeSub.OnNumberChanged);    pub.DoSomething();    }     }     public delegate string GeneralEventHandler();     public class Publishser     {     public event GeneralEventHandler NumberChanged;    public void DoSomething()    {     if (NumberChanged != null)     {     Delegate[] generalEventHandlers = NumberChanged.GetInvocationList();    foreach (Delegate generalEventHandler in generalEventHandlers)     {    GeneralEventHandler mothed = (GeneralEventHandler)generalEventHandler;     string rtn = mothed();     Console.WriteLine(rtn);     System.Threading.Thread.Sleep(2000);     }     }     }     }     public class OneScriber     {     public string OnNumberChanged()     {     return "One Subscriber";     }     }     public class TwoScriber     {     public string OnNumberChanged()     {     return "Two Subscriber";    }     }     public class ThreeScriber     {     public string OnNumberChanged()     {     return "Three Subscriber";     }     }     }

运行结果:

C#开发中事件与委托机制的示例分析

注意到Delegate是GeneralEventHandler 的基类,所以为了触发事件,先要进行一个向下的强制转换,之后才能在其上触发事件,调用所有注册对象的方法。除了使用这种方式以外,还有一种更灵活方式可以调用方法,它是定义在Delegate基类中的DynamicInvoke()方法:

public object DynamicInvoke(params object[] args);

这可能是调用委托最通用的方法了,适用于所有类型的委托。它接受的参数为object[],也就是说它可以将任意数量的任意类型作为参数,并返回单个object对象。上面的DoSomething()方法也可以改写成下面这种通用形式:

代码作如下改动:

namespace DelegateAndEvent    {     class Program     {     static void Main(string[] args)    {     Publishser pub = new Publishser();    OneScriber oneSub = new OneScriber();     TwoScriber twoSub = new TwoScriber();     ThreeScriber threeSub = new ThreeScriber();     pub.NumberChanged += new GeneralEventHandler(oneSub.OnNumberChanged);     pub.NumberChanged += new GeneralEventHandler(twoSub.OnNumberChanged);    pub.NumberChanged += new GeneralEventHandler(threeSub.OnNumberChanged);     List<string> strlist = pub.DoSomething();    foreach (string result in strlist)     Console.WriteLine(result);     System.Threading.Thread.Sleep(5000);     }     }    public delegate string GeneralEventHandler();     public class Publishser    {    public event GeneralEventHandler NumberChanged;     public List<string> DoSomething()     {     List<string> strList = new List<string>();    if (NumberChanged == null) return strList;     Delegate[] generalEventHandlers = NumberChanged.GetInvocationList();     foreach (Delegate generalEventHandler in generalEventHandlers)    {     // GeneralEventHandler mothed = (GeneralEventHandler)generalEventHandler;     string rtn = generalEventHandler.DynamicInvoke(null).ToString();     strList.Add(rtn);    }    return strList;    }     }     public class OneScriber    {     public string OnNumberChanged()    {     return "One Subscriber";     }     }     public class TwoScriber     {     public string OnNumberChanged()     {     return "Two Subscriber";     }     }     public class ThreeScriber     {    public string OnNumberChanged()     {    return "Three Subscriber";     }     }     }

结果如下:

C#开发中事件与委托机制的示例分析

还是一样的结果.

委托的定义会生成继承自MulticastDelegate的完整的类,其中包含Invoke()、BeginInvoke()和EndInvoke()方法。当我们直接调用委托时,实际上是调用了Invoke()方法,它会中断调用它的客户端,然后在客户端线程上执行所有订阅者的方法(客户端无法继续执行后面代码),***将控制权返回客户端。注意到BeginInvoke()、EndInvoke()方法,在.net中,异步执行的方法通常都会配对出现,并且以Begin和End作为方法的开头(最常见的可能就是Stream类的BeginRead()和EndRead()方法了)。它们用于方法的异步执行,即是在调用BeginInvoke()之后,客户端从线程池中抓取一个闲置线程,然后交由这个线程去执行订阅者的方法,而客户端线程则可以继续执行下面的代码。

BeginInvoke()接受“动态”的参数个数和类型,为什么说“动态”的呢?因为它的参数是在编译时根据委托的定义动态生成的,其中前面参数的个数和类型与委托定义中接受的参数个数和类型相同,***两个参数分别是AsyncCallback和Object类型,对于它们更具体的内容,可以参见下一节委托和方法的异步调用部分。现在,我们仅需要对这两个参数传入null就可以了。另外还需要注意几点:

在委托类型上调用BeginInvoke()时,此委托对象只能包含一个目标方法,所以对于多个订阅者注册的情况,必须使用GetInvocationList()获得所有委托对象,然后遍历它们,分别在其上调用BeginInvoke()方法。如果直接在委托上调用BeginInvoke(),会抛出异常,提示“委托只能包含一个目标方法”。

如果订阅者的方法抛出异常,.NET会捕捉到它,但是只有在调用EndInvoke()的时候,才会将异常重新抛出。而在本例中,我们不使用EndInvoke()(因为我们不关心订阅者的执行情况),所以我们无需处理异常,因为即使抛出异常,也是在另一个线程上,不会影响到客户端线程(客户端甚至不知道订阅者发生了异常,这有时是好事有时是坏事)

BeginInvoke()方法属于委托定义所生成的类,它既不属于MulticastDelegate也不属于Delegate基类, 我们需要进行一个向下转换,来获取到实际的委托类型。

示例:

namespace DelegateAndEvent     {     class Program     {     static void Main(string[] args)     {     Publishser pub = new Publishser();     OneScriber oneSub = new OneScriber();    TwoScriber twoSub = new TwoScriber();     ThreeScriber threeSub = new ThreeScriber();     pub.NumberChanged += new GeneralEventHandler(oneSub.OnNumberChanged);     pub.NumberChanged += new GeneralEventHandler(twoSub.OnNumberChanged);     pub.NumberChanged += new GeneralEventHandler(threeSub.OnNumberChanged);    List<string> strlist = pub.DoSomething();     foreach (string result in strlist)    Console.WriteLine(result);     System.Threading.Thread.Sleep(5000);     }    }     public delegate string GeneralEventHandler(object sender,EventArgs e);     public class Publishser     {    public event GeneralEventHandler NumberChanged;    public List<string> DoSomething()     {    List<string> strList = new List<string>();    if (NumberChanged == null) return strList;     Delegate[] generalEventHandlers = NumberChanged.GetInvocationList();     foreach (Delegate generalEventHandler in generalEventHandlers)     {     GeneralEventHandler mothed = (GeneralEventHandler)generalEventHandler;     IAsyncResult result = mothed.BeginInvoke(this, EventArgs.Empty, null, null);    string str = mothed.EndInvoke(result);     strList.Add(str);    }     return strList;    }     }     public class OneScriber     {    public string OnNumberChanged(object sender,EventArgs e)    {     return "One Subscriber";     }    }     public class TwoScriber     {    public string OnNumberChanged(object sender, EventArgs e)     {    return "Two Subscriber";     }     }     public class ThreeScriber     {    public string OnNumberChanged(object sender, EventArgs e)    {     return "Three Subscriber";    }     }     }

结果:

C#开发中事件与委托机制的示例分析

BeginInvoke的另外两个参数分别是AsyncCallback和Object类型,其中AsyncCallback是一个委托类型,它用于方法的回调,即是说当异步方法执行完毕时自动进行调用的方法。它的定义为:

public delegate void AsyncCallback(IAsyncResult ar);

Object类型用于传递任何你想要的数值,它可以通过IAsyncResult的AsyncState属性获得。

感谢各位的阅读!关于“C#开发中事件与委托机制的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: C#开发中事件与委托机制的示例分析

本文链接: https://www.lsjlt.com/news/289158.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C#开发中事件与委托机制的示例分析
    这篇文章给大家分享的是有关C#开发中事件与委托机制的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。概述C#中的委托类似于C或C++中的函数指针。使用委托使程序员可以将方法引用封装在委托对象内。然后可以将该...
    99+
    2023-06-17
  • javascript中事件监听与事件委托的示例分析
    这篇文章主要介绍了javascript中事件监听与事件委托的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。事件监听与事件委托在js中...
    99+
    2024-04-02
  • C#中的委托和事件实例分析
    本文小编为大家详细介绍“C#中的委托和事件实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“C#中的委托和事件实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、定义委托delegate v...
    99+
    2023-06-30
  • js事件流、事件委托与事件阶段的示例分析
    这篇文章主要介绍了js事件流、事件委托与事件阶段的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、事件流HTML 中与 javascript 交互是通过事件驱动来实...
    99+
    2023-06-29
  • JavaScript之事件委托的示例分析
    小编给大家分享一下JavaScript之事件委托的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!事件委托的原理依赖于事件...
    99+
    2024-04-02
  • .NET中委托与接口的示例分析
    这篇文章主要介绍.NET中委托与接口的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!委托:委托是一种定义方法签名的类型。当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联。您可以通过委托实例调用方法...
    99+
    2023-06-17
  • Android事件分发机制示例分析
    Android事件类型 public boolean onTouchEvent(MotionEvent event) { switch (event.getActio...
    99+
    2024-04-02
  • JavaScript中事件委托的示例详解
    目录事件流事件委托结尾大家好,我是前端西瓜哥。今天我们来认识一下事件委托。 所谓事件委托,就是将原本应该在当前元素绑定的事件,放到它的祖先元素上,让祖先元素来委托处理。 事件流 事件...
    99+
    2024-04-02
  • C#中的多播委托和泛型委托实例分析
    这篇“C#中的多播委托和泛型委托实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C#中的多播委托和泛型委托实例分析”文...
    99+
    2023-06-30
  • Ext.js4.2.1中事件机制的示例分析
    这篇文章主要为大家展示了“Ext.js4.2.1中事件机制的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Ext.js4.2.1中事件机制的示例分析”这篇文章吧。一: 简介Ext中的事件...
    99+
    2023-06-04
  • JavaScript中事件机制的示例分析
    这篇文章主要介绍JavaScript中事件机制的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!事件是将JavaScript脚本与网页联系在一起的主要方式,是JavaScrip...
    99+
    2024-04-02
  • Flex事件机制中Flex事件分发和监听的示例分析
    这篇文章给大家分享的是有关Flex事件机制中Flex事件分发和监听的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。什么是Flex事件机制Flex事件可以看作是一种触发机制,当满足了一定的条件后,会触发这个...
    99+
    2023-06-17
  • Android中自定义view中事件分发机制与处理的示例分析
    这篇文章将为大家详细讲解有关Android中自定义view中事件分发机制与处理的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。题引事件只有一个,多个人想要处理,处理的对象不是我们想给的对象就是事件...
    99+
    2023-06-25
  • Flex事件机制的示例分析
    这篇文章主要为大家展示了“Flex事件机制的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Flex事件机制的示例分析”这篇文章吧。什么是Flex事件机制Flex事件可以看作是一种触发机制...
    99+
    2023-06-17
  • 事件冒泡、事件委托、jQuery元素节点操作、滚轮事件与函数节流的示例分析
    这篇文章主要介绍事件冒泡、事件委托、jQuery元素节点操作、滚轮事件与函数节流的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、事件冒泡定义事件冒泡是指在一个对象触发某类...
    99+
    2024-04-02
  • vue中事件机制原理的示例分析
    这篇文章主要介绍了vue中事件机制原理的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。常见的事件机制demo都会包含在这段代码中:&...
    99+
    2024-04-02
  • JS中事件循环机制的示例分析
    小编给大家分享一下JS中事件循环机制的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、JavaScript是单线程的JavaScript 是一种单线程的...
    99+
    2023-06-29
  • nodejs中事件循环机制的示例分析
    这篇文章主要介绍了nodejs中事件循环机制的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。前端开发离不开JavaScript,Javascript是一种web前端语...
    99+
    2023-06-14
  • js中事件传播机制的示例分析
    这篇文章主要介绍js中事件传播机制的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!事件的默认传播机制:  捕获阶段:从外向里依次查找元素  目标阶段:从当前事件源本身的操作 ...
    99+
    2024-04-02
  • javascript中事件执行机制的示例分析
    小编给大家分享一下javascript中事件执行机制的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!先看一段代码各位小伙...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作