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

C#委托和事件练习题

1、考察委托与匿名方法与lamdba表达式 难度:⭐

题目描述
定义一个名为MathOperation的委托,它接受两个int参数并返回一个int结果。

  1. 使用常规方法(命名方法)实现加法操作,并调用委托输出结果。

  2. 使用匿名方法实现乘法操作,并调用委托输出结果。

  3. 使用Lambda 表达式实现减法操作,并调用委托输出结果。

预期输出(传入参数5 和 10)

加法: 15 乘法: 50 减法: -5
using System; public delegate int MathOperation(int a, int b); class Program { // 命名方法 static int Add(int a, int b) => a + b; static void Main() { // 1. 使用命名方法 MathOperation op1 = Add; Console.WriteLine($"加法: {op1(5, 10)}"); // 2. 使用匿名方法 MathOperation op2 = delegate(int a, int b) { return a * b; }; Console.WriteLine($"乘法: {op2(5, 10)}"); // 3. 使用 Lambda 表达式 MathOperation op3 = (a, b) => a - b; Console.WriteLine($"减法: {op3(5, 10)}"); } }

2、考察委托对于回调的使用 难度:⭐⭐

题目描述
创建一个NumberProcessor类,其中包含一个ProcessNumbers方法。该方法接收一个整数数组和一个委托参数operation(该委托定义:delegate int IntOperation(int x);)。
ProcessNumbers方法对数组中的每个元素应用operation,并返回一个新数组。

要求

  1. 编写代码定义上述委托和类。

  2. Main中创建NumberProcessor实例。

  3. 分别传入以下三种处理逻辑,输出原始数组和处理后的数组:

    • 将每个数字平方(x => x * x

    • 将每个数字加 10

    • 将每个数字转为负数(x => -x

示例输入数组{1, 2, 3, 4, 5}

预期输出

原始数组: 1 2 3 4 5 平方后: 1 4 9 16 25 加10后: 11 12 13 14 15 负数后: -1 -2 -3 -4 -5
using System; public delegate int IntOperation(int x); public class NumberProcessor { public int[] ProcessNumbers(int[] numbers, IntOperation operation) { int[] result = new int[numbers.Length]; for (int i = 0; i < numbers.Length; i++) { result[i] = operation(numbers[i]); } return result; } } class Program { static void PrintArray(string title, int[] arr) { Console.Write($"{title}: "); foreach (var num in arr) Console.Write($"{num} "); Console.WriteLine(); } static void Main() { int[] original = { 1, 2, 3, 4, 5 }; PrintArray("原始数组", original); NumberProcessor processor = new NumberProcessor(); int[] squared = processor.ProcessNumbers(original, x => x * x); PrintArray("平方后", squared); int[] added = processor.ProcessNumbers(original, x => x + 10); PrintArray("加10后", added); int[] negated = processor.ProcessNumbers(original, x => -x); PrintArray("负数后", negated); } }

3、考察多播委托 难度:⭐

题目描述
使用多播委托实现一个简单的计算器,支持连续执行多个运算。

要求

  1. 声明委托NumberTransformerdelegate double NumberTransformer(double x);

  2. 实现以下静态方法:

    • AddOne:加1

    • Double:乘以2

    • Square:平方

  3. 使用多播委托按以下顺序处理数值5.0:

    • 先加1,再乘以2,再平方

    • 输出最终结果

  4. 演示如何从多播委托中移除一个方法,并再次调用

预期输出

初始值: 5 执行加1 → 乘以2 → 平方后: 144 移除"乘以2"后,执行加1 → 平方: 36
using System; public delegate double NumberTransformer(double x); class Program { static double AddOne(double x) => x + 1; static double Double(double x) => x * 2; static double Square(double x) => x * x; static void Main() { double value = 5.0; Console.WriteLine($"初始值: {value}"); // 多播委托 NumberTransformer operations = AddOne; operations += Double; operations += Square; double result = operations(value); Console.WriteLine($"执行加1 → 乘以2 → 平方后: {result}"); // 移除Double方法 operations -= Double; result = operations(value); Console.WriteLine($"移除\"乘以2\"后,执行加1 → 平方: {result}"); } }

4、考察事件 难度⭐

题目描述
模拟一个热水器,当水温达到95度时触发警报。要求:

  1. 定义Heater类,包含:

    • 私有字段temperature(温度)

    • BoilWater()方法:每加热一次温度+5,并触发温度变化事件

    • 定义事件TemperatureChanged,传递温度参数

  2. 定义Alarm类,包含方法ShowAlert,当水温≥95度时输出"⚠️ 警报:水快烧开了!"

  3. 定义Display类,包含方法ShowTemperature,每次温度变化都输出当前温度

  4. Main中创建对象并建立事件订阅,模拟加热到100度

预期输出(示例):

当前温度: 20 当前温度: 25 ... 当前温度: 90 当前温度: 95 警报:水快烧开了! 当前温度: 100
using System; public class Heater { private int temperature = 20; // 声明事件(基于自定义委托) public event Action<int> TemperatureChanged; public void BoilWater() { while (temperature <= 100) { Console.WriteLine($"当前温度: {temperature}"); TemperatureChanged?.Invoke(temperature); if (temperature >= 95) temperature += 5; // 超过95后快速加热 else temperature += 5; System.Threading.Thread.Sleep(500); // 模拟加热延迟 } } } public class Alarm { public void ShowAlert(int temp) { if (temp >= 95) Console.WriteLine("警报:水快烧开了!"); } } public class Display { public void ShowTemperature(int temp) { // 已在Heater中输出,此处可留空或做其他处理 } } class Program { static void Main() { Heater heater = new Heater(); Alarm alarm = new Alarm(); Display display = new Display(); heater.TemperatureChanged += alarm.ShowAlert; heater.TemperatureChanged += display.ShowTemperature; heater.BoilWater(); } }

5、考察事件 难度⭐

题目描述

你的手机有一个Battery类,当电量降到20%10%时,需要通知用户界面和扬声器。

要求

  1. 实现Battery

    • 有一个int Level属性(0~100)。

    • 定义一个event Action<int> LowBattery事件,传递当前电量百分比。

    • 提供一个UseBattery(int cost)方法,减少电量。
      每次减少后,如果电量 ≤ 20 且刚刚降到 20 或 10(不能重复触发),就触发LowBattery事件。

  2. 实现两个订阅者

    • PhoneScreen:订阅后,当收到事件时,输出" 电量只剩 {level}%,请充电!"

    • Speaker:订阅后,当电量 ≤ 10% 时额外输出" 滴滴滴 – 电量严重不足"

  3. 主程序演示

    • 创建Battery实例。

    • 订阅PhoneScreenSpeaker

    • 循环调用UseBattery(5)从 100% 降到 0%,观察事件触发次数。

示例输出(部分)

电量只剩 20%,请充电! 电量只剩 10%,请充电! 滴滴滴 – 电量严重不足 电量只剩 5%,请充电! (5% 不再重复触发警告)
using System; public class Battery { private int _level = 100; private bool _hasTriggered20 = false; // 标记20%警告是否已触发过 private bool _hasTriggered10 = false; // 标记10%警告是否已触发过 public int Level { get => _level; private set { _level = Math.Clamp(value, 0, 100); } } // 定义事件:当电量过低时触发,传递当前电量 public event Action<int> LowBattery; // 消耗电量 public void UseBattery(int cost) { if (cost <= 0) return; int oldLevel = Level; Level -= cost; Console.WriteLine($" 用电 {cost}%,电量: {oldLevel}% → {Level}%"); // 检查是否降到 20% 或 10%,且之前未触发过 if (Level <= 20 && !_hasTriggered20 && oldLevel > 20) { _hasTriggered20 = true; OnLowBattery(Level); } else if (Level <= 10 && !_hasTriggered10 && oldLevel > 10) { _hasTriggered10 = true; OnLowBattery(Level); } } // 触发事件的方法(线程安全写法) protected virtual void OnLowBattery(int level) { LowBattery?.Invoke(level); } // 重置标记(可选,用于测试) public void Reset() { _level = 100; _hasTriggered20 = false; _hasTriggered10 = false; } } // 手机屏幕订阅者 public class PhoneScreen { public void OnLowBattery(int level) { Console.WriteLine($" 电量只剩 {level}%,请充电!"); } } // 扬声器订阅者(只在电量≤10%时额外提醒) public class Speaker { public void OnLowBattery(int level) { if (level <= 10) { Console.WriteLine($" 滴滴滴 – 电量严重不足 ({level}%)"); } } } class Program { static void Main() { Battery battery = new Battery(); PhoneScreen screen = new PhoneScreen(); Speaker speaker = new Speaker(); // 订阅事件 battery.LowBattery += screen.OnLowBattery; battery.LowBattery += speaker.OnLowBattery; // 从 100% 消耗到 0% while (battery.Level > 0) { battery.UseBattery(5); System.Threading.Thread.Sleep(100); // 稍微减慢输出速度 } Console.WriteLine("\n 测试完成。"); } }

6、考察事件,模拟了winfrom中的事件使用(推荐做完这道题之后去思考winform中事件的逻辑) 难度⭐⭐⭐

题目表述:

你需要实现一个温度监控系统,当温度超过某个阈值时触发警报。

要求使用C# 事件(event)来实现观察者模式中的通知机制,不允许手动编写观察者列表和遍历通知代码。

1. 定义事件参数类TemperatureEventArgs

  • 继承自EventArgs

  • 包含属性:

    • double Temperature(当前温度)

    • bool ExceedThreshold(是否超过阈值)

2. 实现TemperatureSensor类(被观察者)

字段:

  • double currentTemperature

  • double threshold(报警阈值)

事件:

  • 定义一个事件TemperatureChanged,使用标准的.NET事件模式(EventHandler<TemperatureEventArgs>

方法:

  • void CheckTemperature(double newTemp)
    当新温度与当前温度不同时:

    • 更新currentTemperature

    • 判断是否超过阈值

    • 触发TemperatureChanged事件,传递温度信息和是否超阈值

3. 实现Alarm类(观察者 / 事件订阅者)

方法:

  • void OnTemperatureChanged(object sender, TemperatureEventArgs e)
    输出格式:

    • 正常时:"温度变化:{e.Temperature}°C,未超过阈值"

    • 超阈值时:"⚠️ 警报!温度 {e.Temperature}°C 已超过阈值!"

4. 测试代码要求

static void Main() { var sensor = new TemperatureSensor(threshold: 30); var alarm = new Alarm(); // 使用 += 订阅事件 sensor.TemperatureChanged += alarm.OnTemperatureChanged; sensor.CheckTemperature(25); // 正常 sensor.CheckTemperature(25); // 相同温度,不触发事件 sensor.CheckTemperature(32); // 超过阈值 }

期望输出:

温度变化:25°C,未超过阈值 警报!温度 32°C 已超过阈值!
using System; // 1. 事件参数类 public class TemperatureEventArgs : EventArgs { public double Temperature { get; } public bool ExceedThreshold { get; } public TemperatureEventArgs(double temperature, bool exceedThreshold) { Temperature = temperature; ExceedThreshold = exceedThreshold; } } // 2. 被观察者(事件发布者) public class TemperatureSensor { private double currentTemperature; private double threshold; // 事件声明(使用标准 .NET 模式) public event EventHandler<TemperatureEventArgs> TemperatureChanged; public TemperatureSensor(double threshold) { this.threshold = threshold; } public void CheckTemperature(double newTemp) { // 温度未变化,不触发事件 if (Math.Abs(currentTemperature - newTemp) < 0.001) return; currentTemperature = newTemp; bool isExceed = currentTemperature > threshold; // 触发事件(标准安全写法) OnTemperatureChanged(new TemperatureEventArgs(currentTemperature, isExceed)); } // 触发事件的受保护虚方法(符合 .NET 规范) protected virtual void OnTemperatureChanged(TemperatureEventArgs e) { TemperatureChanged?.Invoke(this, e); } } // 3. 观察者(事件订阅者) public class Alarm { public void OnTemperatureChanged(object sender, TemperatureEventArgs e) { if (e.ExceedThreshold) { Console.WriteLine($" 警报!温度 {e.Temperature}°C 已超过阈值!"); } else { Console.WriteLine($"温度变化:{e.Temperature}°C,未超过阈值"); } } } // 4. 测试 class Program { static void Main() { var sensor = new TemperatureSensor(threshold: 30); var alarm = new Alarm(); sensor.TemperatureChanged += alarm.OnTemperatureChanged; sensor.CheckTemperature(25); // 正常 sensor.CheckTemperature(25); // 相同温度,不触发 sensor.CheckTemperature(32); // 超过阈值 } }
http://www.cnnetsun.cn/news/1792805.html

相关文章:

  • OpenClaw技能开发入门:为百川2-13B-4bits模型定制专属自动化模块
  • 华为OD机试真题 新系统 - 准备生日礼物(Py/Java/C/C++/Js/Go)
  • PowerMeter:嵌入式电能计量开源库设计与实现
  • Redis怎样优雅地关闭AOF_在运行期间动态将appendonly设置为no
  • PCB布局设计核心原则与实战技巧
  • DFRobot MGC3130电容式手势传感器库深度解析
  • 大疆c板开发例程
  • 沈阳路灯工厂名声
  • MQTT快速入门
  • 以太网和CAN,WIFI
  • 美团推荐算法研究员面试题精选:10道高频考题+答案解析(附PDF)
  • Codeforces Round 1091 (Div. 2) and CodeCraft 26 2217
  • 实时行情系统设计:从协议选择到高可用架构,再到数据源选型钩
  • 【Hot 100 刷题计划】 LeetCode 17. 电话号码的字母组合 | C++ 回溯算法经典模板
  • GitHub 推送该用 SSH 还是 HTTPS?一篇讲透两种登录方式的区别
  • 余弦调度策略
  • [Linux][虚拟串口]x一个特殊的字节露
  • 打理多个微信不用慌,告别切换内耗很简单
  • 深度解码:华为IPD流程管理体系L1-L5最佳实践与数字化转型架构全景(PPT)
  • 【无标题】鑫博XB931M wifi模块
  • WPF新手村教程(七)—— 终章(MVVM架构初见杀)疾
  • 把握 AI 时代核心:孩子自主能力的脑能构建路径
  • 面向对象 方法重写 继承 多态 final 相关案例
  • Linux I/O 演进史:从管道到零拷贝,一篇串起个服务端核心原语纠
  • Kiro IDE remote extension host terminated unexpectedly #4231 官方状态:**未修复**(2026最新实测)
  • OpenClaw安装使用指南
  • 2026届最火的六大AI辅助论文网站解析与推荐
  • plog嵌入式C++日志库:轻量、零开销与跨平台实践
  • 嵌入式网络接口设计:硬件选型与软件优化实践
  • M5StickC-Plus嵌入式开发全指南:ESP32-PICO-D4硬件解析与低功耗实践