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

【C#】委托

1.委托 delegate

委托是一种引用类型,能封装一个或者多个方法。类似于C++中的函数指针,但是比指针更灵活、安全。

C++中函数指针通常用于:
1.动态调用函数:在编译时不调用,而是在运行时。
2.回调机制:异步操作中
3.实现策略模式:允许在运行时选择算法或策略
4.简化代码:将函数作为参数传入,封装好只用一个函数调用。

简单的委托代码:

using System;namespace DelegateExample
{// 定义一个委托类型,用于封装数学操作public delegate double MathOperation(double a, double b);class Program{static void Main(string[] args){// 创建委托实例并指向不同的数学操作方法// 两种写法,都可以MathOperation add = new MathOperation(Add);MathOperation subtract = new MathOperation(Subtract);MathOperation multiply = Multiply;MathOperation divide = Divide;// 使用委托调用方法double x = 10;double y = 5;Console.WriteLine($"Adding {x} and {y}: {add(x, y)}");Console.WriteLine($"Subtracting {y} from {x}: {subtract(x, y)}");Console.WriteLine($"Multiplying {x} and {y}: {multiply(x, y)}");Console.WriteLine($"Dividing {x} by {y}: {divide(x, y)}");Console.ReadKey();}// 加法public static double Add(double a, double b){return a + b;}// 减法public static double Subtract(double a, double b){return a - b;}// 乘法public static double Multiply(double a, double b){return a * b;}// 除法public static double Divide(double a, double b){if (b == 0){throw new DivideByZeroException("Divider cannot be zero.");}return a / b;}}
}

上述代码可能感受不直观,下面是两组对比:
前者是正常的函数实现,可以发现代码重复量很多,方法结构、传参方式很相似。

using System;
using System.Collections.Generic;class Program
{static double Sum(List<double> values){double result = 0;foreach (double value in values){result += value;}return result;}static double Average(List<double> values){if (values.Count == 0) return 0;return Sum(values) / values.Count;}static double Max(List<double> values){if (values.Count == 0) return 0;double result = values[0];foreach (double value in values){if (value > result){result = value;}}return result;}static double Min(List<double> values){if (values.Count == 0) return 0;double result = values[0];foreach (double value in values){if (value < result){result = value;}}return result;}static void Main(){List<double> values = new List<double> { 1.5, 2.5, 3.5, 4.5 };Console.WriteLine("Sum: " + Sum(values));Console.WriteLine("Average: " + Average(values));Console.WriteLine("Max: " + Max(values));Console.WriteLine("Min: " + Min(values));}
}

下面是用函数委托来实现:

using System;
using System.Collections.Generic;class Program
{// 定义一个委托类型,用于封装数学操作public delegate double MathOperation(double a, double b);// 定义一个通用的操作方法static double ApplyOperation(List<double> values, MathOperation operation, double initialValue){double result = initialValue;foreach (double value in values){result = operation(result, value);}return result;}// 各种具体的操作方法static double SumOperation(double a, double b) => a + b;static double MaxOperation(double a, double b) => (a > b) ? a : b;static double MinOperation(double a, double b) => (a < b) ? a : b;// 封装后的方法static double Sum(List<double> values) => ApplyOperation(values, SumOperation, 0);static double Average(List<double> values) => values.Count == 0 ? 0 : Sum(values) / values.Count;static double Max(List<double> values) => values.Count == 0 ? 0 : ApplyOperation(values, MaxOperation, values[0]);static double Min(List<double> values) => values.Count == 0 ? 0 : ApplyOperation(values, MinOperation, values[0]);static void Main(){List<double> values = new List<double> { 1.5, 2.5, 3.5, 4.5 };Console.WriteLine("Sum: " + Sum(values));Console.WriteLine("Average: " + Average(values));Console.WriteLine("Max: " + Max(values));Console.WriteLine("Min: " + Min(values));}
}

2.Lambda表达式

本质为匿名函数,现代C#已经用lambda表达式逐步代替匿名函数了。
语法格式:
(参数列表)=> {语句序列};

因为lambda依附于委托,所以也要遵循委托的限制。

1.参数列表中的参数个数应该由相应的委托限制。
2.参数列表中限制只有一个参数时,参数列表()括号可以省略。
3.当编译器能自动推断参数类型时,参数列表中可以不写类型。
4.委托声明中对参数加入了ref和out限制,lambda中也要加上。
5.当右侧语句序列中只有一条语句,{}花括号可以省略。
6.有返回值,必须用return;如果语句序列中只有一个时,return可以省略。
7.如果委托有返回值类型,则lambda也必须有同类型返回值。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • wireshark与tcpdump使用
  • Hadoop-15-Hive 元数据管理与存储 Metadata 内嵌模式 本地模式 远程模式 集群规划配置 启动服务 3节点云服务器实测
  • python基础语法 006 内置函数
  • IPython 性能评估工具的较量:%%timeit 与 %timeit 的差异解析
  • Spring源码十三:非懒加载单例Bean
  • MySQL SQL100道基础练习题
  • axios的使用,处理请求和响应,axios拦截器
  • 秋招突击——7/5——复习{}——新作{跳跃游戏II、划分字母区间、数组中的第K个大的元素(模板题,重要)、前K个高频元素}
  • C++ 参数传递
  • Linux系统的服务——以Centos7为例
  • 迅睿CMS 后端配置项没有正常加载,上传插件不能正常使用
  • Python酷库之旅-第三方库Pandas(008)
  • node_sqlite3.node is not a valid win32 application
  • 工地/矿区/电力/工厂/环卫视频智能安全监控反光衣AI检测算法的原理及场景应用
  • RPC与REST
  • php的引用
  • (三)从jvm层面了解线程的启动和停止
  • css属性的继承、初识值、计算值、当前值、应用值
  • Electron入门介绍
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • Java小白进阶笔记(3)-初级面向对象
  • JSONP原理
  • Python_网络编程
  • 使用API自动生成工具优化前端工作流
  • Java总结 - String - 这篇请使劲喷我
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • #pragam once 和 #ifndef 预编译头
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (4.10~4.16)
  • (zt)最盛行的警世狂言(爆笑)
  • (二)十分简易快速 自己训练样本 opencv级联lbp分类器 车牌识别
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (力扣)循环队列的实现与详解(C语言)
  • (四)Controller接口控制器详解(三)
  • (原創) 物件導向與老子思想 (OO)
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • *上位机的定义
  • .ai域名是什么后缀?
  • .cfg\.dat\.mak(持续补充)
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选
  • .NET Core中的时区转换问题
  • .NET MVC之AOP
  • .NET 药厂业务系统 CPU爆高分析
  • .NET/C# 中设置当发生某个特定异常时进入断点(不借助 Visual Studio 的纯代码实现)
  • .net流程开发平台的一些难点(1)
  • @LoadBalanced 和 @RefreshScope 同时使用,负载均衡失效分析
  • [AX]AX2012 R2 出差申请和支出报告
  • [BIZ] - 1.金融交易系统特点
  • [C# 开发技巧]实现属于自己的截图工具
  • [C#]C#学习笔记-CIL和动态程序集
  • [C#]OpenCvSharp结合yolov8-face实现L2CS-Net眼睛注视方向估计或者人脸朝向估计
  • [C++随笔录] 红黑树