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

【.NET Core】委托(Delegate)应用详解

【.NET Core】委托(Delegate)应用详解

文章目录

  • 【.NET Core】委托(Delegate)应用详解
    • 一、概述
    • 二、委托(Delegate)定义
    • 三、基础委托(Delegate) - 无返回值委托
    • 四、基础委托(Delegate) - 有返回值委托
    • 五、MulticastDelegate 多播委托
    • 六、匿名方法
    • 七、匿名委托之Action
    • 八、匿名委托之Func
    • 九、委托总结
    • 十、参考资料

一、概述

委托(Delegate)是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。委托(Delegate)类似于C或C++中函数指针。委托是将方法调用者和目标方法动态关联起来,委托是一个类,实质上是一个类,可以通过委托隐藏方法,虽然委托定义方法的参数及其返回值,但是它并不是和方法一个层级的。

委托(Delegate)可以将方法当作另一个方法的参数来进行传递,这种方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。

二、委托(Delegate)定义

声明一个委托的语法如下:

deletgate <return type> <delegate-name> <parameter list>
  • delegate 定义委托关键字
  • return type 返回类型 (与方法返回值相同)
  • delegate-name 委托的命名
  • parameter list 参数列表 (与方法入参相同)

声明委托步骤

  1. 声明一个delegate对象,它应当与要传统的方法具有相同的参数和返回值类型。
  2. 创建delegate对象,new Delegate传入参数
  3. 通过delegate调用方法,并返回值。

代码演示

delegate int DegaAdd(int a,int b,int c);
public int add(int a,int b,int c){return a+b+c;
}
public static void Main(String[] args){DegaAdd degaAdd=new DegaAdd(add);int respVal =degaAdd(2,3,4);Console.WriteLine(respVal);
}

三、基础委托(Delegate) - 无返回值委托

public class Program 
{public delegate void DelegateNoReturn(string param1, string param2);public static void NoReturn(string param1, string param2) {Console.WriteLine(param1+" "+param2+".");}public static void Main(string[] args) {DelegateNoReturn delegateNoReturn;delegateNoReturn = NoReturn;delegateNoReturn("Hello", "Delegate");}
}

四、基础委托(Delegate) - 有返回值委托

public class Program 
{public delegate void DelegateNoReturn(string param1, string param2);public delegate string DelegateHaveReturn(string param1, string param2);public static void NoReturn(string param1, string param2) {Console.WriteLine(param1+" "+param2+".");}public static string HaveReturn(string param1, string param2) {return ("有参数Delegate:"+param1 + " " + param2 + ".");}public static void Main(string[] args){DelegateHaveReturn delegateHaveReturn;delegateHaveReturn = HaveReturn;string response = delegateHaveReturn("Hello", "Delegate");Console.WriteLine(response);}
}

五、MulticastDelegate 多播委托

多播委托(MulticastDelegate)是指在一个委托中注册多个方法,在注册方法时可以在委托中使用加号运算符或者减号运算符来实现添加或撤销方法。

创建一个方法集合类

public class DelegateMethod
{public static void Method1(){Console.WriteLine("委托方法一.");}public void Method2() {Console.WriteLine("委托方法二.");}public void Method3(){Console.WriteLine("委托方法三.");}
}

创建一个多播委托

public class Program 
{public delegate void OrderDelegate();public static void Main(string[] args) {OrderDelegate orderDelegate = new OrderDelegate(DelegateMethod.Method1);orderDelegate += new DelegateMethod().Method2;orderDelegate += new DelegateMethod().Method3;orderDelegate();}
}

输出

委托方法一.
委托方法二.
委托方法三.

六、匿名方法

匿名方法(Anonymous methods)提供了一种传递代码块作为委托参数的技术。匿名方法是没有名称只有主体的方法。

在匿名方法中您不需要指定返回类型,它是从方法体内的return语句推断的。

.net 3.0以前的版本,匿名方法是通过使用delegate关键字创建委托实例来声明的

delegate void ValueChange(int n);
...
ValueChange vchange=delegate(int x)
{Console.WriteLine("Anonymous Method:{0}",x);
}

对于高于C#3.0 的版本中,可以用Lambda表达式进行取代匿名方法,并用Lambda表达式作为编写内联代码的首选方式,因为它更简洁。

button1.Click+=delegate(Object o,EventArgs e)
{Console.WriteLine("Anonymous Method:");
}

七、匿名委托之Action

Action是.NET Framework内置的泛型委托,可以使用Action委托以参数形式传递方法,而不用显示声明自定义的委托。封装的方法必须与此委托定义的方法签名相对应。也就是说,封装的方法必须具有一个通过值传递给它的参数,并并且不能有返回值。

Action的特点:

  1. 参数个数0~16
  2. 没有返回值
public class ActionDemo
{public void Operate() {Action action1 = new Action(Method1);Action<int, int> action2 = new Action<int, int>(Method2);action1();action2(1, 2);Action<int ,string,string> action3= delegate (int i1 ,string i2,string s){Console.WriteLine($"这里是三个参数的Action委托,参数1的值是:{i1},参数2的值是:{i2},参数3的值是:{s}");};action3(1,"a","abc");}public void Method1() {Console.WriteLine("This Method1");}public void Method2(int a,int b) { Console.WriteLine("This Method2"); }}

八、匿名委托之Func

Func匿名委托与Action相似,但是Func委托代表有返回类型的委托。

Func至少0个输入参数,至多16个输入参数,根据返回值泛型返回。必须有返回值,不可void

Func 表示没有输入参参,返回值为int类型的委托。

Func<object,string,int> 表示传入参数为object, string ,返回值为int类型的委托。

Func<object,string,int> 表示传入参数为object, string, 返回值为int类型的委托。

Func<T1,T2,T3,int> 表示传入参数为T1,T2,T3(泛型),返回值为int类型的委托。

public void Operate() 
{// 无参数,只要返回值 Func<int> fun1 = new Func<int>(FunWithNoPara);int result1 = fun1();Console.WriteLine(result1);Console.WriteLine("----------------------------");Func<int> fun2 = delegate { return 19; };int result2 = fun2();Console.WriteLine(result2);Console.WriteLine("----------------------------");Func<int> fun3 = () => { return 3; };int result3 = fun3();Console.WriteLine(result3);Console.WriteLine("----------------------------");//有一个参数,一个返回值Func<int, int> fun4 = new Func<int, int>(FunWithPara);int result4 = fun4(4);Console.WriteLine($"这里是一个参数一个返回值的方法,返回值是:{result4}");Console.WriteLine("----------------------------");// 使用委托Func<int, string> fun5 = delegate (int i) { return i.ToString(); };string result5 = fun5(5);Console.WriteLine($"这里是一个参数一个返回值的委托,返回值是:{result5}");Console.WriteLine("----------------------------");// 使用匿名委托Func<int, string> fun6 = (int i) =>{return i.ToString();};string result6 = fun6(6);Console.WriteLine($"这里是一个参数一个返回值的匿名委托,返回值是:{result6}");Console.WriteLine("----------------------------");// 多个输入参数Func<int, string, bool> fun7 = new Func<int, string, bool>(FunWithMultiPara);bool result7 = fun7(2, "2");Console.WriteLine($"这里是有多个输入参数的方法,返回值是:{result7}");Console.WriteLine("----------------------------");// 使用委托Func<int, string, bool> fun8 = delegate (int i, string s){return i.ToString().Equals(s) ? true : false;};bool result8 = fun8(2, "abc");Console.WriteLine($"这里是有多个输入参数的委托,返回值是:{result8}");Console.WriteLine("----------------------------");// 使用匿名委托Func<int, string, bool> fun9 = (int i, string s) =>{return i.ToString().Equals(s) ? true : false;};bool result9 = fun9(45, "ert");Console.WriteLine($"这里是有多个输入参数的匿名委托,返回值是:{result9}");Console.ReadKey();}public int FunWithNoPara(){return 10;}public int FunWithPara(int i){return i;}public bool FunWithMultiPara(int i, string s){return i.ToString().Equals(s) ? true : false;}

九、委托总结

  1. 委托封装了包含特殊返回值和一组参数行为,类似于单一方法接口。
  2. 委托类型声明中描述的类型签名决定了方法哪个方法可用于委托实例,同时也决定了调用签名。
  3. 创建委托实例,需要一个方法以及(对于实例方法来说)调用方法的目标。
  4. 委托实例是不易变的。
  5. 每个委托实例都包含一个调用列表——一个操作列表。
  6. 委托实例可以合并到一起,也可以从一个委托实例中删除另一个。

十、参考资料

https://learn.microsoft.com/zh-cn/dotnet/api/system.func-1?view=net-7.0

https://learn.microsoft.com/zh-cn/dotnet/csharp/programming-guide/delegates/

相关文章:

【.NET Core】委托(Delegate)应用详解

【.NET Core】委托&#xff08;Delegate&#xff09;应用详解 文章目录 【.NET Core】委托&#xff08;Delegate&#xff09;应用详解一、概述二、委托&#xff08;Delegate&#xff09;定义三、基础委托(Delegate) - 无返回值委托四、基础委托(Delegate) - 有返回值委托五、Mu…...

【LeetCode:1457. 二叉树中的伪回文路径 | 二叉树 + DFS +回文数】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…...

《golang设计模式》第三部分·行为型模式-06-备忘录模式(Memento)

文章目录 1. 概述1.1 角色1.2 类图 2. 代码示例2.1 设计2.2 代码2.3 类图 1. 概述 备忘录&#xff08;Memento&#xff09;用于在不破坏目标对象封装特性的基础上&#xff0c;将目标对象内部的状态存储到外部对象中&#xff0c;以备之后恢复状态时使用。 1.1 角色 Originato…...

Cache学习(4):Cache分配策略Cache更新策略Cache逐出策略

Cache的数据流 常用名词 Allocation 分配Eviction 驱逐分配策略和更新策略分别为当产生Cache miss和Cache hit的时候数据流的具体行为 1 Cache分配策略&#xff08;Cache Allocation Policy&#xff09; Cache的分配策略是指不同情况下为数据分配Cache Line的不同行为。Cac…...

角色管理--产品经理岗

研发组织管理--角色管理--产品经理岗 定位 相对稳定和简单产品的独立产品打造者&#xff0c;复杂产品的辅助者 所需资质 校招新人&#xff0c;拥有灵性拥有基础的产品力&#xff08;认知&#xff0c;设计&#xff0c;创新&#xff0c;推进&#xff0c;学习&#xff09;Axur…...

SQL数据迁移实战:从产品层级信息到AB测试表

文章目录 创建表插入数据清空数据表数据迁移和筛选查询数据结论 创建表 首先&#xff0c;代码中定义了两个表格&#xff1a;dim_prod_hierarchy_info 和 app_abtest_product_info&#xff0c;都位于 test 数据库中。 dim_prod_hierarchy_info 表用于存储产品层级信息&#xf…...

VMware系列:VMware安装Android虚拟机

VMware系列:VMware安装Android虚拟机 一. 下载镜像这里提供了三种下载镜像方式,也就是三个下载链接,这里推荐百度网盘下载二. 使用VMware Workstation Pro 创建新的虚拟机操作系统应该可以选择任意一个,笔者只试过下图中,如果读者感兴趣可以多试几个,但笔者不保证每个都可…...

链接1:编译器驱动程序

文章目录 GNU编译器示例编译 GNU编译器 GNU编译器&#xff08;GNU Compiler&#xff09;是由自由软件基金会&#xff08;Free Software Foundation&#xff0c;FSF&#xff09;开发和维护的一套编译器集合。这些编译器主要用于编译各种编程语言的源代码&#xff0c;将其转换为…...

经典滑动窗口试题(二)

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、水果成篮1、题目讲解2、讲解算法思路3、代码实现 二、找到字符串中所有字母异位词1、题目…...

easyexcel指定sheet页动态给行列加背景色

需求 1、easyexcel&#xff0c;有多个sheet页&#xff0c;某些sheet页的行、列动态需要加背景色。 2、扩展支持cellStyle标记单元格超过64000 import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.write.handler.…...

设计模式在实际业务中应用 - 模版方法

1. 业务背景 作者在工作中主要主导 A 业务线的系统建设&#xff0c;A 业务线主要是零售场景酒水的售卖与即时配送服务。为了方便运营在自研系统中对多平台商品进行管理而开发的三方平台商品管理功能&#xff0c;本次介绍的模版方法模式则是在该功能开发过程中的落地实践。 2.…...

BGP综合实验

任务如下&#xff1a; 1.AS1存在两个环回&#xff0c;一个地址为192.168.1.0/24该地址不能在任何协议中宣告 AS3存在两个环回&#xff0c;一个地址为192.168.2.0/24该地址不能在任何协议中宣告&#xff0c;最终要求这两个环回可以互相通讯 2.整个AS2的IP地址为172.16.0.0/16&…...

Global Surface Summary of the Day 全球逐日气象站点数据 GSOD数据集

数据名称 Global Surface Summary of the Day 数据内容 数据包含以下气象要素的日值观测数据&#xff1a; 气压&#xff1a;平均气压、海平面气压&#xff1b;气温&#xff1a;平均气温、日最高气温、日最低气温&#xff1b;湿度&#xff1a;露点温度&#xff08;需自行换算…...

Harmony OS4开发入门

代码地址&#xff1a; https://gitee.com/BruceLeeAdmin/harmonyos/tree/master 项目目录介绍 ArkTS介绍 简单案例&#xff1a; State times: number 0/*数据类型&#xff1a;stringnumberany: 不确定类型&#xff0c;可以是任意类型*/State msg: string "hello"…...

.net core 事务

在 .NET Core 中&#xff0c;可以使用 Entity Framework Core 来实现事务处理。下面是一个简单的示例&#xff0c;展示了如何在 .NET Core 中使用 Entity Framework Core 来创建和执行事务&#xff1a; using System; using Microsoft.EntityFrameworkCore; using System.Tran…...

【Python】python天气数据抓取与数据分析(源码+论文)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…...

MPPT工作流程及算法和硬件的选择

MPPT算法选择 目前&#xff0c;MPPT算法有开路电压比率(离线)、短路电流比率(离线)、观察调节(在线)、极限追踪控制法(在线)。 在光伏控制系统中&#xff0c;因为日照、温度等条件的变化&#xff0c;光伏电池的输出功率也是在不断变化的&#xff0c;为保证使得光伏电池的输出功…...

C#,《小白学程序》第十九课:随机数(Random)第六,随机生成任意长度的大数(BigInteger)

1 文本格式 using System; using System.Linq; using System.Text; using System.Collections.Generic; /// <summary> /// 大数的&#xff08;加减乘除&#xff09;四则运算、阶乘运算 /// 乘法计算包括小学生算法、Karatsuba和Toom-Cook3算法 /// 除法运算为 Truffer…...

每日一练【移动零】

一、题目描述 283. 移动零 - 力扣&#xff08;LeetCode&#xff09; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 二、题目解析 可以…...

QT修改windowTitle的名字以及图片

1.修改名字:点击ui的QMainWindow,然后找到windowTitle的选项修改即可 2.修改windowTitle的图片,依旧是找到windowIcon,选择资源,这个资源可以是你放到qrc里面的图片也可以是外置的图片 3.然后运行就可以看到效果了...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...