一、任务一:用委托模拟做饭——>开饭——>吃饭的过程
(1)一家三口,妈妈做饭,爸爸妈妈和孩子都要吃饭
二、核心类结构分析
1. 抽象基类 - Person
abstract class Person
{
public abstract void Eat();
}
-
定义抽象方法Eat(),强制所有子类实现吃饭行为
-
体现面向对象的抽象和多态特性
2. 具体实现类
Mother类 - 事件发布者
class Mother : Person
{
public Action beginEat; // 关键:委托字段
public override void Eat()
{
Console.WriteLine("妈妈吃饭");
}
public void DoFood()
{
Console.WriteLine("妈妈做饭");
Console.WriteLine("妈妈做饭做好了");
// 触发事件
if (beginEat != null)
{
beginEat(); // 执行所有注册的方法
}
}
}
Father和Son类 - 事件订阅者
class Father : Person
{
public override void Eat()
{
Console.WriteLine("爸爸吃饭");
}
}
class Son : Person
{
public override void Eat()
{
Console.WriteLine("孩子吃饭");
}
}
三、委托机制详解
1. 委托定义
public Action beginEat;
-
使用
Action委托,表示无参数无返回值的方法 -
作为事件通知机制的核心
2. 订阅机制
m.beginEat += f.Eat; // 爸爸订阅
m.beginEat += s.Eat; // 孩子订阅
m.beginEat += m.Eat; // 妈妈自己也订阅
-
使用
+=操作符实现多播委托 -
支持多个方法的注册
3. 事件触发
if (beginEat != null)
{
beginEat(); // 统一通知所有订阅者
}
-
空值检查避免异常
-
一句调用触发所有注册方法
四、任务一完整代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace 进阶测试
{
abstract class Person
{
public abstract void Eat();
}
class Mother : Person
{
public Action beginEat;
public override void Eat()
{
Console.WriteLine("妈妈吃饭");
}
public void DoFood()
{
Console.WriteLine("妈妈做饭");
Console.WriteLine("妈妈做饭做好了");
//执行委托函数
if (beginEat != null)
{
beginEat();
}
}
}
class Father : Person
{
public override void Eat()
{
Console.WriteLine("爸爸吃饭");
}
}
class Son : Person
{
public override void Eat()
{
Console.WriteLine("孩子吃饭");
}
}
class Program
{
static void Main(string[] args)
{
Mother m = new Mother();
Father f = new Father();
Son s = new Son();
//告诉妈妈 一会做好了 我要吃
m.beginEat += f.Eat;
m.beginEat += s.Eat;
m.beginEat += m.Eat;
//做饭
m.DoFood();
}
}
}
五、任务二:用委托来模拟数据处理
(1)怪物死亡后,玩家要加10块钱
(2)界面要更新数据,成就要累加怪物击杀
数
六、核心架构设计
1. 事件中心 - Monster类(事件发布者)
class Monster
{
public Action<Monster> deadDoSomthing; // 关键委托:死亡事件
public int money = 10; // 怪物价值
public void Dead()
{
Console.WriteLine("怪物死亡");
if (deadDoSomthing != null)
{
deadDoSomthing(this); // 触发事件,传递自身引用
}
deadDoSomthing = null; // 事件处理后清空委托
}
}
-
使用
Action<Monster>泛型委托,传递怪物实例本身 -
空值检查避免空引用异常
-
事件触发后清空委托,防止重复触发
2. 事件订阅者 - 三个子系统
Player类(玩家系统)
class Player
{
private int myMoney = 0;
public void MonsterDeadDoSomthing(Monster m)
{
myMoney += m.money; // 增加金钱
Console.WriteLine("现在有{0}元钱", myMoney);
}
}
Panel类(界面系统)
class Panel
{
private int nowShowMoney = 0;
public void MonsterDeadDo(Monster m)
{
nowShowMoney += m.money; // 更新界面显示
Console.WriteLine("当前面板显示{0}元钱", nowShowMoney);
}
}
CJ类(成就系统)
class CJ
{
private int nowKillMonsterNum = 0;
public void MonsterDeadDo(Monster m)
{
nowKillMonsterNum += 1; // 累计击杀数
Console.WriteLine("当前击杀了{0}怪物", nowKillMonsterNum);
}
}
七、完整代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace 进阶测试
{
//怪物死亡后,玩家要加10块钱,界面要更新数据
//成就要累加怪物击杀数,请用委托来模拟实现这些功能
//只用写核心逻辑表现这个过程,不用写的太复杂
class Monster
{
//当怪物死亡时 把自己作为参数传出去
public Action<Monster> deadDoSomthing;
//怪物成员变量 特征 价值多少钱
public int money = 10;
public void Dead()
{
Console.WriteLine("怪物死亡");
if (deadDoSomthing != null)
{
deadDoSomthing(this);
}
//一般情况下 委托关联的函数 有加 就有减(或者直接清空)
deadDoSomthing = null;
}
}
class Player
{
private int myMoney = 0;
public void MonsterDeadDoSomthing(Monster m)
{
myMoney += m.money;
Console.WriteLine("现在有{0}元钱", myMoney);
}
}
class Panel
{
private int nowShowMoney = 0;
public void MonsterDeadDo(Monster m)
{
nowShowMoney += m.money;
Console.WriteLine("当前面板显示{0}元钱", nowShowMoney);
}
}
class CJ
{
private int nowKillMonsterNum = 0;
public void MonsterDeadDo(Monster m)
{
nowKillMonsterNum += 1;
Console.WriteLine("当前击杀了{0}怪物", nowKillMonsterNum);
}
}
class Program
{
static void Main(string[] args)
{
Monster monster = new Monster();
Player p = new Player();
Panel panel = new Panel();
CJ cj = new CJ();
monster.deadDoSomthing += p.MonsterDeadDoSomthing;
monster.deadDoSomthing += panel.MonsterDeadDo;
monster.deadDoSomthing += cj.MonsterDeadDo;
monster.Dead();
monster.Dead();
Monster monster2 = new Monster();
monster2.deadDoSomthing += p.MonsterDeadDoSomthing;
monster2.deadDoSomthing += panel.MonsterDeadDo;
monster2.deadDoSomthing += cj.MonsterDeadDo;
monster2.Dead();
}
}
}
C#委托与事件实战演练
230

被折叠的 条评论
为什么被折叠?



