【C#】两个简单例子理解委托与事件
程序员文章站
2022-06-15 23:19:17
...
一、委托
委托是把方法作为参数来传递,这个参数的类型就是委托。
使用委托的步骤:
1.定义几个要作为参数被传递的方法,这些方法的签名(参数、返回值)要一致。
2.声明一个委托类型,参数、返回值与上述方法的签名一致。委托的声明看起来像定义一个方法一样,但带有delegate关键字,并且没有花括号。
3. 定义需要使用这个委托类型作为参数的方法。
4.调用这个方法。此时可以根据需要,把不同的方法名作为参数传递进去。
using System;
namespace DelegatePractice1
{
//声明一个委托类型,处理角色碰撞到不同的物体。
public delegate string CollisionHandler(int value);
class Program
{
static void Main(string[] args)
{
//委托是将方法作为参数来传递,参数的类型即“委托”
//向PlayerCollision传递所需方法的名称作为实参时,即可实例化这个委托
//先吃一个血包
PlayerCollision(GetHPBag,5);
//接着捡一个装备
PlayerCollision(GetEquipItem,10);
Console.ReadKey();
}
//定义两个方法,分别处理不同物体。
//1、处理血包
private static string GetHPBag(int value)
{
string result = "现在执行了GetHPBag方法,血量增加"+ value;
return result;
}
//2、处理装备
private static string GetEquipItem(int value)
{
string result = "现在执行了GetEquipItem方法,防御力增加" + value;
return result;
}
//定义需要使用这个委托类型作为参数的方法
private static void PlayerCollision(CollisionHandler collisionType,int value)
{
string s = collisionType(value);//委托在此处被实例化了
Console.WriteLine(s);
}
}
}
二、事件
事件是对订阅和发布的封装。仅在声明此事件的类内部才支持赋值操作符,且只能在这个类里才能触发事件通知。
事件的使用:
1. 声明委托
2.发布者声明事件
3.订阅者定义一个要响应此事件的方法
4.使用“+=”操作符链接发布者与订阅者:发布者对象.事件 += 订阅者对象.响应事件的方法;
5.发布者还需要定义一个引发这个事件的方法。
using System;
namespace DelegatePractice
{
//事件的发布者
class Publisher
{
//声明委托
public delegate void BulletHandler(string type, int value);
//定义事件成员
public event BulletHandler OnBulletHit;
//定义一个用来引发事件的方法
public void ShootBullet(string type, int value)
{
if (OnBulletHit != null)
{
OnBulletHit(type, value);
}
else
{
Console.WriteLine("没有人订阅此事件");
}
}
}
//事件的订阅者
class Subscriber
{
public void OnHandleBulletEvent(string type, int value)
{
Console.WriteLine("用{0}射中了目标,血量{1}", type, value);
}
}
class Program
{
static void Main(string[] args)
{
//创建出订阅者和发布者的实例
Publisher shooter = new Publisher();
Subscriber aim = new Subscriber();
//注册发布者对事件的关注
shooter.OnBulletHit += aim.OnHandleBulletEvent;
Console.WriteLine("按A或B键射击,按C取消订阅。按ESC退出");
string key="";
while (key != "Escape")
{
key = Console.ReadKey().Key.ToString();
//发布者引发事件
switch (key)
{
case "A":
shooter.ShootBullet("治疗弹", +10);
break;
case "B":
shooter.ShootBullet("子弹", -10);
break;
case "C":
shooter.OnBulletHit -= aim.OnHandleBulletEvent;
Console.WriteLine("已取消对事件的订阅");
break;
}
}
Console.WriteLine("测试结束,按任意键退出");
Console.ReadKey();
}
}
}