首页 > 代码库 > C#事件
C#事件
今天来说一下C#的事件,说起事件不得不提委托,回调函数。其实这三者最本质的方面就是委托(函数指针)的运用,委托只是最基础的部分,定义了一个可以指向其他方法(函数) 的对象(简单理解就是一个指针变量)。其实很多帖子都谈到委托,回调函数和事件,但是都讲的很笼统,大神的理解固然深刻,但是对于初学者不易理解。委托的理解可以如上述所说,而回调函数则可以理解为一个方法在运行时调用了另一个方法,即它的入口参数中需要另外一个方法。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CallBack { /// <summary> /// 通过sayhello方法调用hello方法,看似多次一举,其实代表了一种思路,即 /// 把方法的行为与行为主体(本例中为name)分开 /// </summary> /// <param name="h"></param> public delegate void newDelegate(string h); class Program { static void Main(string[] args) { SayHello("Andy", Hello); Console.ReadKey(); } //调用函数 static void SayHello(string name,newDelegate Hello) { Hello(name); } //回调函数 static void Hello(string name) { Console.WriteLine(name + "你好!"); } } }
回调函数与事件是以委托为基础的,事件与回调函数在本质上都属于委托的应用,所以在本质上两者并没有太大界限,在很多解释回调函数的例子中,由于写的比较复杂,其实已经属于事件机制。所谓事件其实也是一个方法调用另一个方法。对事件进行细分流程可以这样理解:
1、首先要发布事件
public delegate void reactEventhander();//定义一个委托 //此处event可以不加,程序依旧可以运行,只是在类外部可以对事件进行修改,增加event可以避免 public event reactEventhander RegularReact;//发布两个事件 public event Eventhander MagicReact;
2、定义事件触发的条件(也可以无条件触发)
//定义事件触发的条件 //攻击者发动普通攻击时,被攻击者的反应 public void RegularAttack() { Console.WriteLine("发起了普通攻击!"); if(RegularReact!=null)//判断事件是否被订阅 { RegularReact(); } } public void MagciAttack() { Console.WriteLine("发起了魔法攻击!"); if (RegularReact != null)//判断事件是否被订阅 { MagicReact(); } }
3、事件被订阅
public Enemy1(Attacker a) { //Enemy1对事件进行了订阅,遭受攻击时反应 a.RegularReact += new reactEventhander(a_RegularAttacek); a.MagicReact += new reactEventhander(a_MagciAttacek); }
4、最后事件发生
通过下边例子说明。此例子来模拟两个小怪(enemy1、enemy2)同时遭受attacker时的受伤害情况(enemy2由于级别较低,掉血较多)
/// <summary> /// 模拟两个小怪(enemy1、enemy2)同时遭受attacker时的受伤害情况 /// enemy2由于级别较低,掉血较多 /// attacker 可以进行普通攻击和魔法攻击,同时发布两种攻击发起时,遭受者的反应 /// enemy1、enemy2对遭受两种攻击时的反应进行了订阅 /// </summary> public delegate void reactEventhander();//定义一个委托 class Attacker { public event reactEventhander RegularReact;//发布两个事件 public event reactEventhander MagicReact; //定义事件触发的条件 //攻击者发动普通攻击时,被攻击者的反应 public void RegularAttack() { Console.WriteLine("发起了普通攻击!"); if(RegularReact!=null)//判断事件是否被订阅 { RegularReact(); } } public void MagciAttack() { Console.WriteLine("发起了魔法攻击!"); if (RegularReact != null)//判断事件是否被订阅 { MagicReact(); } } } class Enemy1 { public Enemy1(Attacker a) { //Enemy1对事件进行了订阅,遭受攻击时反应 a.RegularReact += new reactEventhander(a_RegularAttacek); a.MagicReact += new reactEventhander(a_MagciAttacek); } //受到普通攻击时的反应 public void a_RegularAttacek() { Console.WriteLine("Enemy1遭受普通攻击,掉血100!"); } //受到魔法攻击时的反应 public void a_MagciAttacek() { Console.WriteLine("Enemy1遭受魔法攻击,掉血100!"); } } class Enemy2 { public Enemy2(Attacker a) { //Enemy1对事件进行了订阅,遭受攻击时反应 a.RegularReact += new reactEventhander(a_RegularAttacek); a.MagicReact += new reactEventhander(a_MagciAttacek); } //受到普通攻击时的反应 public void a_RegularAttacek() { Console.WriteLine("Enemy2遭受普通攻击,掉血300!"); } //受到魔法攻击时的反应 public void a_MagciAttacek() { Console.WriteLine("Enemy2遭受魔法攻击,掉血300!"); } } class Program { static void Main(string[] args) { Attacker att = new Attacker(); Enemy1 e1 = new Enemy1(att); Enemy2 e2 = new Enemy2(att); att.RegularAttack(); att.MagciAttack(); Console.ReadKey(); } }
仔细会看此例子,剥去所有的乱七八糟的,也不过是attacker的regularattack和magicattack方法调用了enemy1/2的a_RegularAttacek和a_MagciAttacek方法,只不过是通过attacker发布的两个事件进行订阅的。从此小例子上来讲,为了帮助理解,此处完全可以去掉两个event,在两个enemy的a_RegularAttacek和a_MagciAttacek方法中加入委托类型的入口参数。但是事件的这种机制思想确实很重要的,以后会慢慢体会到的。
C#事件
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。