C#委托和事件练习题
1、考察委托与匿名方法与lamdba表达式 难度⭐题目描述定义一个名为MathOperation的委托它接受两个int参数并返回一个int结果。使用常规方法命名方法实现加法操作并调用委托输出结果。使用匿名方法实现乘法操作并调用委托输出结果。使用Lambda 表达式实现减法操作并调用委托输出结果。预期输出(传入参数5 和 10加法: 15 乘法: 50 减法: -5using 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并返回一个新数组。要求编写代码定义上述委托和类。在Main中创建NumberProcessor实例。分别传入以下三种处理逻辑输出原始数组和处理后的数组将每个数字平方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 -5using 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、考察多播委托 难度⭐题目描述使用多播委托实现一个简单的计算器支持连续执行多个运算。要求声明委托NumberTransformerdelegate double NumberTransformer(double x);实现以下静态方法AddOne加1Double乘以2Square平方使用多播委托按以下顺序处理数值5.0先加1再乘以2再平方输出最终结果演示如何从多播委托中移除一个方法并再次调用预期输出初始值: 5 执行加1 → 乘以2 → 平方后: 144 移除乘以2后执行加1 → 平方: 36using 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度时触发警报。要求定义Heater类包含私有字段temperature温度BoilWater()方法每加热一次温度5并触发温度变化事件定义事件TemperatureChanged传递温度参数定义Alarm类包含方法ShowAlert当水温≥95度时输出⚠️ 警报水快烧开了定义Display类包含方法ShowTemperature每次温度变化都输出当前温度在Main中创建对象并建立事件订阅模拟加热到100度预期输出示例当前温度: 20 当前温度: 25 ... 当前温度: 90 当前温度: 95 警报水快烧开了 当前温度: 100using System; public class Heater { private int temperature 20; // 声明事件基于自定义委托 public event Actionint 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%时需要通知用户界面和扬声器。要求实现Battery类有一个int Level属性0~100。定义一个event Actionint LowBattery事件传递当前电量百分比。提供一个UseBattery(int cost)方法减少电量。每次减少后如果电量 ≤ 20 且刚刚降到 20 或 10不能重复触发就触发LowBattery事件。实现两个订阅者PhoneScreen订阅后当收到事件时输出 电量只剩 {level}%请充电。Speaker订阅后当电量 ≤ 10% 时额外输出 滴滴滴 – 电量严重不足。主程序演示创建Battery实例。订阅PhoneScreen和Speaker。循环调用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 Actionint 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 currentTemperaturedouble threshold报警阈值事件定义一个事件TemperatureChanged使用标准的.NET事件模式EventHandlerTemperatureEventArgs方法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 EventHandlerTemperatureEventArgs 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); // 超过阈值 } }