当前位置: 首页 > news >正文

C#练习题——委托练习

一、任务一:用委托模拟做饭——>开饭——>吃饭的过程

(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();}}
}
http://www.dtcms.com/a/395735.html

相关文章:

  • 【TS4】简单的typescript练手项目
  • 前端学习手册-JavaScript函数与回调(十一)
  • Unity小游戏接入抖音敏感词检测
  • 【2025最新】01 Spring Boot 第一个小程序 for VS Code - 通过 Spring Initializr 网站创建
  • 算法面试(3)------YOLO 的核心思想是什么?YOLOv1 到 v8 的演进路线?
  • docker 部署gitlib
  • SpringBoot3.5.5版本大坑
  • Lightroom Classic 2025专业级数字照片管理与后期处理全解析
  • 交叉编译工具链
  • 前端构建工具有哪些?常用前端构建工具推荐、前端构建工具对比与最佳实践
  • 【RocketMQ入门到精通 | 4】工作原理:indexFile索引文件
  • PPIO首发上线DeepSeek-V3.1-Terminus
  • 《嵌入式驱动(一):系统移植》
  • C语言(长期更新)第22讲:文件操作(一)
  • 财务管控——解读79页集团财务业务管控方法及信息化应用案例【附全文阅读】
  • 火语言RPA:解锁开发者工作流的“自动化密码”
  • 用户行为数据可视化
  • jdbc-数据更新与删除
  • 【GitLab】GitLab-CI(shell方式)入门配置
  • Python入门 | 三个if语句程序作业和基础语法笔记
  • BeanPropertyRowMapper
  • 深入解析Java中String的不可变性
  • windows-安装kafka并启动
  • linux 驱动私有数据
  • 信息系统监理师软考备考指南:组织协调与沟通管理专题精讲
  • 【开题答辩全过程】以 JAVA农产品销售系统为例,包含答辩的问题和答案
  • Python 网络爬虫生态全景综述
  • MCP— Model Context Protocol(模型上下文协议)
  • 解决ubuntu无法连接上security.ubuntu.com:80 (185.125.190.81)的问题
  • SHAP分析 | MATLAB实现XGBoost极限梯度提升树多输入单输出回归预测+SHAP可解释分析分析(预测新数据,多指标评价)