C#基础加强篇—委托、Lambda表达式和事件(下)

3.事件

事件作为C#中的一种类型,为类和类的实例定义发出通知的能力,从而将事件和可执行代码捆绑在了一起。事件是对象发送的消息,以发信号通知操作的发生。操作可能是由用户交互引起的,也可能是由某些其他的程序逻辑触发的。引发(触发)事件的对象叫做事件发送方,捕获事件并对其做出响应的对象叫做事件接收方。

C#事件是按“发布——预定”的方式工作。先在一个类中公布事件,然后就可以在任意数量的类中对事件预定。在事件通信中,事件发送方类并不知道哪个对象或方法将接收到(处理)它所引发的事件。所需要的是在源和接收方之间存在一个媒介(或类似指针的机制),这一媒介就是委托。

事件功能是由3个互相联系的元素提供:提供事件数据的类、事件委托和引发事件的类。如果想要类引发名为EventName的事件,需要以下元素:

(1)持有事件数据的类:名为EventNameEventArgs。该类必须继承System.EventArgs类。如果不自定义持有事件数据的类,就使用System.EventArgs类。

(2)事件的委托:名为EventNameEventHandler

(3)引发该事件的类。该类必须提供:

a.事件声明:public event EventNameEventHandler  EventName;

b.引发事件的方法:名为OnEventName

(4)定义使用此事件的类。所有这些类都应该包括:

创建事件源对象。使用定义的构造函数创建包含事件定义的类的对象。

定义事件处理程序,也就是定义与事件关联的方法。

将事件源对象注册到事件处理处理程序。使用委托对象和“+=”运算符和“-=”运算符将一个或多个方法与事件源中的事件关联。

C#事件机制基于委托实现,首先要定义一个委托:

public delegate void EventHandler(object from,myEventArgs e); //from表示发生事件的对象

声明事件的格式:event 事件的委托名 事件名

public event EventHandler TextOut;

事件的激活一般写成:

if(TextOut!=null)

TextOut(this,new EventArgs());

订阅事件  +=  evsrc.TextOut+=new EventSource.EventHandler(CatchEvent);

取消订阅  -=  evsrc.TextOut-=new EventSource.EventHandler(CatchEvent);

下面再来看一个示例:

 1   public class MyEventArgs:EventArgs
 2     { //定义事件包含数据
 3
 4         private string StrText;
 5         public MyEventArgs(string StrText)
 6         {
 7             this.StrText = StrText;
 8         }
 9         public string GetStrText
10         {
11             get
12             {
13                 return StrText;
14             }
15         }
16     }
17
18     public class EventSource
19     {//发布事件的类
20
21         MyEventArgs EvArgs = new MyEventArgs("触发事件");
22         public delegate void EventHandler(object from, MyEventArgs e);//定义委托
23         public event EventHandler TextOut;//定义事件
24         public void TriggerEvent()//激活事件的方法
25         {
26             if(TextOut!=null)
27             {
28                 TextOut(this, EvArgs);
29             }
30         }
31     }
32     class Test
33     {//订阅事件的类
34         static void Main(string[] args)
35         {
36             EventSource evsrc = new EventSource();
37             evsrc.TextOut += new EventSource.EventHandler(CatchEvent);//订阅事件
38             evsrc.TriggerEvent();//触发事件
39             Console.WriteLine("--------------");
40
41             evsrc.TextOut -= new EventSource.EventHandler(CatchEvent);//取消订阅事件
42             evsrc.TriggerEvent();//由于订阅已取消,什么也不执行
43             Console.WriteLine("--------------");
44
45             Test theApp=new Test();
46             evsrc.TextOut += new EventSource.EventHandler(theApp.InstanceCatch);
47             evsrc.TriggerEvent();
48         }
49         private static void CatchEvent(object from, MyEventArgs e)
50         {//事件处理程序
51             Console.WriteLine("CatchEvent:{0}", e.GetStrText);
52         }
53         private void InstanceCatch(object from, MyEventArgs e)
54         {//事件处理程序
55             Console.WriteLine("InstanceCatch:{0}", e.GetStrText);
56         }
57     }

可以对照着上面的介绍,来找一下事件的几个相关元素。

委托、Lamada表达式、事件的一些基础知识完。。。。

这是我第一次写博客,本人也还是在大学里摸索的渣渣,几乎都是书上的一些内容,感觉自己一个字一个字打出来印象会比较深刻,理解也更到位,大神勿喷。。。

时间: 2024-10-27 23:23:46

C#基础加强篇—委托、Lambda表达式和事件(下)的相关文章

ASP.NET MVC学前篇之Lambda表达式、依赖倒置

前言 随着上篇文章的阅读,可能有的朋友会有疑问,比如(A.Method(xxx=>xx>yy);)类似于这样的函数调用语句,里面的xxx=>xx>yy这些到底是怎么用的? 依赖倒置原则的实现也会在本篇幅的最后来粗略的讲解一下. 本篇没有核心的主题,如果说要强制定义的话就是这些内容都是基础知识,是为了后续学习MVC框架做铺垫. 1 Lambda Lambda表达式在日常的开发中很常见,使用Lambda表达式可以自由的定义函数体并且精简代码量,那么Lambda表达式是什么呢? Lamb

委托、Lambda表达式、事件系列06,使用Action实现观察者模式

在"实现观察者模式(Observer Pattern)的2种方式"中,曾经通过接口的方式.委托与事件的方式实现过观察者模式.本篇体验使用Action实现此模式. 就举一个足球场上的例子,当裁判吹响终场哨,胜队庆祝,失败队落寞.把裁判看作是被观察者,比赛中的两队看作是观察者. 裁判作为被观察者需要提供一个Action委托供观察者方法注册. public class Referee { public Action DoSth; public void ISayGameOver() { Co

个人总结:匿名委托+内置委托+Lambda表达式

匿名委托+内置委托+Lambda表达式 概要 在实际开发中,项目开发框架不同,用到的技术是不一样的,这里总结一下用Linq开发,ORM之EF开发会大量使用的Lambda表达式; 正文 之前提过.Net有一套扩展在IEumberable<T>泛型接口的扩展方法,本文是从这个基础继续总结; 1.void Action<in T>: 先拿一个ForEach()来讲: public void ForEach(Action<T> action); 这个Action<T>

委托、Lambda表达式、事件系列07,使用EventHandler委托

谈到事件注册,EventHandler是最常用的. EventHandler是一个委托,接收2个形参.sender是指事件的发起者,e代表事件参数. □ 使用EventHandler实现猜拳游戏 使用EventHandler实现一个猜拳游戏,每次出拳,出剪刀.石头.布这三者的其中一种. 首先抽象出一个被观察者,其中提供了事件,提供了执行事件的方法. public class FistGame { public string FistName { get; set; } public event

委托、Lambda表达式、事件系列05,Action委托与闭包

来看使用Action委托的一个实例: static void Main(string[] args) { int i = 0; Action a = () => i++; a(); a(); Console.WriteLine(i); } 结果是期望能的2.但令人好奇的是:栈上的变量i是如何传递给Action委托的? 反编译进行查看,首先看Main方法对应的IL代码: 再看c_DisplayClass1的IL代码: 从中可以看出:→在托管堆上创建了一个名为c_DisplayClass1的实例→把

委托、Lambda表达式、事件系列04,委托链是怎样形成的, 多播委托

在"委托.Lambda表达式.事件系列01,委托是什么,委托的基本用法,委托的Method和Target属性"中,反编译委托,发现委托都是多播委托. 既然委托是多播委托,我们可以通过"+="把多个方法赋给委托变量,这样就形成了一个委托链, 它是怎样形成的?来看下面的例子: namespace ConsoleApplication3 { internal delegate void MySayDel(string msg); class Program { stati

委托、Lambda表达式、事件系列03,从委托到Lamda表达式

在"委托.Lambda表达式.事件系列02,什么时候该用委托"一文中,使用委托让代码简洁了不少. namespace ConsoleApplication2 { internal delegate bool MyCalculateDelegate(int val); class Program { static void Main(string[] args) { IEnumerable<int> source = new List<int>(){2, 3, 4

委托、Lambda表达式、事件系列02,什么时候该用委托

假设要找出整型集合中小于5的数. static void Main(string[] args) { IEnumerable<int> source = new List<int>(){2, 3, 4, 5, 6, 7, 8, 9,10, 11}; var result = GetNumbersLessThanFive(source); foreach (int n in result) { Console.WriteLine(n); } } static IEnumerable&

C#基础加强篇---委托、Lamada表达式和事件(中)

2.Lamada表达式     C#共有两种匿名函数:匿名方法和Lamada表达式.在2.0之前的C#版本中,创建委托的唯一方法是使用命名方法.C#2.0中引入了匿名方法,匿名方法就是没有名称的方法.从C#3.0开始,就可以使用一种新语法把实现代码赋予委托——Lamada表达式. 在了解Lamada表达式之前,我们先来了解一下匿名方法.用匿名方法定义委托的语法与之前的没有区别,但在实例化时就有了一些区别. 使用命名方法创建的委托 1 class Program 2 { 3 private del