C#委托和事件
2021-02-10 06:15
委托的定义:它定义了可代表的方法的类型委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。说明白一些就是将方法作为参数,进行传递
在书写委托时首先应该进行定义:public delegate void GetDelegate(string name);
其所对应的关键字时delegate首先应该进行声明,形式为:
public delegate void GetDelegate(string name); class MainClass { private static void English(string name) { Console.WriteLine ("Morning:"+name); } private static void Chinese(string name) { Console.WriteLine ("早上好:"+name); } private static void DelegatePeople(string name,GetDelegate makeMethod) { makeMethod (name); } public static void Main(string[] args) {
//调用代码方式如下 } }
其中有五种使用方式:
//第一种调用方法 DelegatePeople ("wangbaosong",English); DelegatePeople ("王宝松", Chinese); //第二种调用方法 // GetDelegate delegate1=English; // delegate1 += Chinese; // DelegatePeople ("小明", delegate1); //第三种调用方法 // GetDelegate delegate1=English; // delegate1 += Chinese; // delegate1 ("小明"); //第四种调用方法 // GetDelegate delegate1=new GetDelegate(English); // delegate1 += Chinese; // delegate1 ("小明"); //第五种调用方法 // GetDelegate delegate1=new GetDelegate(English); // delegate1 += Chinese; // delegate1 ("小明"); // delegate1 -= English; // delegate1 ("baosong");
注意点:委托变量在进行第一个变量赋值的时候用等于号,然后再次进行添加的时候就必须用+=,如果上来直接用+=那样程序会报错,当点击-=时能够进行程序的解绑
在委托定义过程中还能够进行匿名委托和lambda表达式(格式为:(参数)=>{要执行的方法})
代码如下:
delegate匿名委托
主方法中写入: //匿名委托方法只用到1次 NiMing nm=delegate(string str){ Console.WriteLine ("匿名委托:"+str); }; //调用 nm("委托的其他形式"); //使用匿名委托将传入的字符串转换成大写 Upper upper = delegate(string str) { return str.ToUpper(); }; Console.WriteLine (upper("ffffffffffffffffff")); 类定义前写入:
public delegate void NiMing(string str);
public delegate string Upper(string str);
lambda表达式: public delegate void Action(int a); 主方法中写入: Action action = (int a) => { a=a*100; Console.WriteLine (a); }; //调用 action(7);
事件:事件在类中声明且生成,并且通过使用同一个类或者其他类型的委托和时间去处理程序,包含事件的类用于发布事件,一般发布者,其他接收时间的类成为订阅者在发布者类中委托去调用订阅者类中的方法,进行事件处理。
class MainClass { public delegate void Publish(string name); //发布者类 public class FB { //事件:关键字event //将委托封装成了一个类型 public event Publish makePub; //方法 //发布的方法: public void MakePublish(string name) { if (makePub!=null) { Console.WriteLine ("小说更新了--------"); //调用事件(委托) makePub(name); } } } //订阅者 public class XiaoMing { public static void Print(string name) { Console.WriteLine (name+"可了不得了,终于更新了!!!!"); } } public class XiaoLi { public static void PrintB(string name) { Console.WriteLine ("才更新,取关!!!!!!"); } } public class XiaoWang { public static void PrintC(string name) { Console.WriteLine ("可算更新了,养肥了再去看吧!!!!"); } } public static void Main(string[] args) { //发布者 FB fb = new FB (); //让订阅者去绑定发布者 fb.makePub+=XiaoLi.PrintB; fb.makePub += XiaoMing.Print; fb.makePub += XiaoWang.PrintC; //调用 fb.MakePublish("小东"); } }
注意:在事件使用过程中需要注意事件与委托不一样的,事件只能用+=,-=进行添加和解绑,无法进行=号的运算,如果进行=号运算,程序会报错,event定义后 其中的委托字段就会变为私有的只有进行 += -=的时候 是共有的
一个例题来表示委托和事件的联合应用
题目要求:敌人出现在英雄范围内,英雄就发起攻击!!!public delegate void playerDelegate();
//被观察者 public class Player { //事件 public event playerDelegate playerEvent; //武器攻击力 private string WeaponName; private int AttackValue; //构造函数 public Player(string weaponName,int attackValue) { this.AttackValue = attackValue; this.WeaponName = weaponName; } //玩家攻击怪物的方法 public void PlayerAttack() { Console.WriteLine ("玩家使用的武器名字为:"+this.WeaponName+"" + ",攻击力为:"+this.AttackValue); //如果事件列表不为空,通知事件的观察者执行自己相应的操作 if (playerEvent!=null) { playerEvent (); } } } //敌人:观察者 public class Enemy { private string EnemyName; private int AttackValue; public Enemy(string name,int attack) { this.EnemyName = name; this.AttackValue = attack; } //攻击玩家 public void EnemyAttack() { Console.WriteLine ("敌人:" + this.EnemyName + "攻击,对玩家造成了" + this.AttackValue + "点伤害"); } } class MainClass { public static void Main(string[] args) { Player player = new Player ("大榔头",999); Enemy enemy1 = new Enemy ("铁柱",30); Enemy enemy2 = new Enemy ("铁蛋",80); Enemy enemy3 = new Enemy ("铁球",60); Enemy enemy4 = new Enemy ("铁皮",100); Enemy enemy5 = new Enemy ("铁饭碗",40); //事件绑定 player.playerEvent+=enemy1.EnemyAttack; player.playerEvent+=enemy2.EnemyAttack; player.playerEvent+=enemy3.EnemyAttack; player.playerEvent+=enemy4.EnemyAttack; player.playerEvent+=enemy5.EnemyAttack; //调用攻击方法 player.PlayerAttack(); } }输出结果为:
玩家使用的武器名字为:大榔头,攻击力为:999
敌人:铁柱攻击,对玩家造成了30点伤害
敌人:铁蛋攻击,对玩家造成了80点伤害
敌人:铁球攻击,对玩家造成了60点伤害
敌人:铁皮攻击,对玩家造成了100点伤害
敌人:铁饭碗攻击,对玩家造成了40点伤害
在C#中委托就相当于定义的一个字段,而事件就如同属性一样对委托进行封装保存
以上是自己的理解,希望对大家有帮助