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

C# delegate 委托使用教程

什么是委托?

委托是定义方法签名的引用类型数据类型,可以定义委托的变量,就像其他数据类型一样,可以引用与委托具有相同签名的任何方法。

它允许方法作为参数传递,并允许事件驱动编程。它们提供了一种以类型安全的方式封装方法引用的方法。

  • 委托是一种类型,类似于 C++ 的函数指针,但更安全和灵活。

  • 委托可以存储对方法的引用(或者多个方法)。

  • 委托是实现事件和回调的基础。

为什么使用委托?

  1. 类型安全:委托提供一种类型安全的方法来处理方法引用,确保方法签名与委托签名相匹配。

  2. 灵活性:它们允许将方法作为参数传递,从而实现动态方法调用和回调机制。

  3. 事件处理:委托是 C# 中事件处理的基础

创建和使用委托

示例一
  1. 定义委托
// 定义一个委托类型
public delegate void PrintDelegate(string message);
  1. 定义方法
public class Printer
{public void PrintMessage(string message){Console.WriteLine("Message: " + message);}public void PrintUppercase(string message){Console.WriteLine("Uppercase: " + message.ToUpper());}
}
  1. 使用委托
class Program
{static void Main(string[] args){// 实例化委托Printer printer = new Printer();PrintDelegate printDelegate = new PrintDelegate(printer.PrintMessage);// 调用委托printDelegate("Hello, Delegates!");// 替换委托目标printDelegate = printer.PrintUppercase;printDelegate("Hello again!");}
}

输出

Message: Hello, Delegates!
Uppercase: HELLO AGAIN!
示例二
  1. 定义委托
public delegate void MyDelegate(string msg);
  1. 定义方法
// 方法1:实例化委托,把方法名作为参数传进去
MyDelegate del = new MyDelegate(MethodA);// 方法2:直接把方法名赋值给委托的实例
MyDelegate del = MethodA; // 方法3:把Lambda表达式赋值给委托的实例
MyDelegate del = (string msg) => Console.WriteLine(msg);// 目标方法
static void MethodA(string message)
{Console.WriteLine(message);
}
  1. 使用委托
// 方法1:使用委托实例名.Invoke调用目标方法
del.Invoke("Hello World!");// 方法2:直接使用委托实例名作为方法调用
del("Hello World!");

将委托作为参数传递

方法可以有一个委托类型的参数,也就是回调函数

public delegate void MyDelegate(string msg); //declaring a delegateclass Program
{static void Main(string[] args){MyDelegate del = ClassA.MethodA;InvokeDelegate(del);del = ClassB.MethodB;InvokeDelegate(del);del = (string msg) => Console.WriteLine("Called lambda expression: " + msg);InvokeDelegate(del);}static void InvokeDelegate(MyDelegate del) // MyDelegate type parameter{del("Hello World");}
}class ClassA
{static void MethodA(string message){Console.WriteLine("Called ClassA.MethodA() with parameter: " + message);}
}class ClassB
{static void MethodB(string message){Console.WriteLine("Called ClassB.MethodB() with parameter: " + message);}
}

多播代理

委托可以指向多个方法,指向多个方法的委托称为多播委托。++= 运算符将函数添加到调用列表中,--= 运算符将其删除

如果委托返回一个值,那么在调用多播委托时将返回最后分配的目标方法的值

多播无返回值的示例

public delegate void MyDelegate(string msg); //declaring a delegateclass Program
{static void Main(string[] args){MyDelegate del1 = ClassA.MethodA;MyDelegate del2 = ClassB.MethodB;MyDelegate del = del1 + del2; // combines del1 + del2del("Hello World");MyDelegate del3 = (string msg) => Console.WriteLine("Called lambda expression: " + msg);del += del3; // combines del1 + del2 + del3del("Hello World");del = del - del2; // removes del2del("Hello World");del -= del1 // removes del1del("Hello World");}
}class ClassA
{static void MethodA(string message){Console.WriteLine("Called ClassA.MethodA() with parameter: " + message);}
}class ClassB
{static void MethodB(string message){Console.WriteLine("Called ClassB.MethodB() with parameter: " + message);}
}

多播有返回值的示例

public delegate int MyDelegate(); //declaring a delegateclass Program
{static void Main(string[] args){MyDelegate del1 = ClassA.MethodA;MyDelegate del2 = ClassB.MethodB;MyDelegate del = del1 + del2; Console.WriteLine(del());// returns 200}
}class ClassA
{static int MethodA(){return 100;}
}class ClassB
{static int MethodB(){return 200;}
}

泛型委托

泛型委托的定义方式与委托相同,但使用泛型类型参数或返回类型,设置目标方法时必须指定泛型类型。

public delegate T add<T>(T param1, T param2); // generic delegateclass Program
{static void Main(string[] args){add<int> sum = Sum;Console.WriteLine(sum(10, 20));add<string> con = Concat;Console.WriteLine(conct("Hello ","World!!"));}public static int Sum(int val1, int val2){return val1 + val2;}public static string Concat(string str1, string str2){return str1 + str2;}
}

Func 委托

特性

  • 用于有返回值的方法。

  • 最后一个泛型参数是返回类型。

  • 支持 0 到 16 个输入参数。

  • Func 委托不允许 refout 参数

  • Func 委托类型可以与匿名方法或 lambda 表达式一起使用

Func 是包含在 System 命名空间中的泛型委托。它有零个或多个输入参数和一个输出参数,最后一个参数被认为是输出参数。

可以包含 0 到 16 个不同类型的输入参数,但是它必须包含一个用于结果的输出参数。

Func 委托签名

// 尖括号 <> 中的最后一个参数被视为返回类型,其余参数被视为输入参数类型
namespace System
{    public delegate TResult Func<in T, out TResult>(T arg);
}
普通方法赋值给 Func 委托
class Program
{static int Sum(int x, int y){return x + y;}static void Main(string[] args){Func<int, int, int> add = Sum;int result = add(10, 10);Console.WriteLine(result); // 输出20}
}
Lambda 表达式赋值给 Func 委托
Func<int> getRandomNumber = () => new Random().Next(1, 100);Func<int, int, int> Sum = (x, y) => x + y;

Action 委托

特性

  • 用于无返回值的方法。

  • 支持 0 到 16 个输入参数。

  • Action 委托类型可以与匿名方法或 lambda 表达式一起使用

Action 委托是 System 命名空间中定义的委托类型,与 Func 委托相同,只是 Action 委托不返回值。即 Action 委托可以与具有 void 返回类型的方法一起使用。

定义类似于 Action 的委托
public delegate void Print(int val);static void ConsolePrint(int i)
{Console.WriteLine(i);
}static void Main(string[] args)
{           Print prnt = ConsolePrint;prnt(10); // 输出10
}
使用 Action 委托代替上面的
static void ConsolePrint(int i)
{Console.WriteLine(i);
}static void Main(string[] args)
{Action<int> printActionDel = ConsolePrint;printActionDel(10);
}
匿名方法赋值给 Action 委托
static void Main(string[] args)
{Action<int> printActionDel = delegate(int i){Console.WriteLine(i);};printActionDel(10);
}
Lambda 表达式赋值给 Action 委托
static void Main(string[] args)
{Action<int> printActionDel = i => Console.WriteLine(i);printActionDel(10);
}

Predicate (谓词) 委托

谓词是类似于 FuncAction 委托的委托,它表示一个包含一组条件的方法,并检查传递的参数是否满足这些条件。谓词委托方法必须接受一个输入参数并返回一个布尔值:truefalse

Predicate签名

普通方法赋值给谓词委托
static bool IsUpperCase(string str)
{return str.Equals(str.ToUpper());
}static void Main(string[] args)
{Predicate<string> isUpper = IsUpperCase;bool result = isUpper("hello world!!");Console.WriteLine(result);
}
匿名方法赋值给谓词委托
static void Main(string[] args)
{Predicate<string> isUpper = delegate(string s) { return s.Equals(s.ToUpper());};bool result = isUpper("hello world!!");
}
Lambda 表达式赋值给谓词委托
static void Main(string[] args)
{Predicate<string> isUpper = s => s.Equals(s.ToUpper());bool result = isUpper("hello world!!");
}
ActionFuncLINQ 的结合

筛选和映射操作:

List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };// 使用 Func 进行映射
List<int> squaredNumbers = numbers.Select(x => x * x).ToList();
Console.WriteLine("Squared Numbers: " + string.Join(", ", squaredNumbers));// 使用 Predicate 或 Func 进行过滤
List<int> evenNumbers = numbers.Where(x => x % 2 == 0).ToList();
Console.WriteLine("Even Numbers: " + string.Join(", ", evenNumbers));

匿名方法

C# 中的匿名方法可以使用 delegate 关键字定义,并可以分配给委托类型的变量。

普通用法

public delegate void Print(int value);static void Main(string[] args)
{Print print = delegate(int val) { Console.WriteLine("Inside Anonymous method. Value: {0}", val); };print(100);
}

匿名方法可以访问外部函数中定义的变量

public delegate void Print(int value);static void Main(string[] args)
{int i = 10;Print prnt = delegate(int val) {val += i;Console.WriteLine("Anonymous method: {0}", val); };prnt(100);
}

匿名方法作为参数

public delegate void Print(int value);class Program
{public static void PrintHelperMethod(Print printDel,int val){ val += 10;printDel(val);}static void Main(string[] args){PrintHelperMethod(delegate(int val) { Console.WriteLine("Anonymous method: {0}", val); }, 100);}
}

匿名方法用作事件处理程序

saveButton.Click += delegate(Object o, EventArgs e)
{ System.Windows.Forms.MessageBox.Show("Save Successfully!"); 
};

相关文章:

C# delegate 委托使用教程

什么是委托&#xff1f; 委托是定义方法签名的引用类型数据类型&#xff0c;可以定义委托的变量&#xff0c;就像其他数据类型一样&#xff0c;可以引用与委托具有相同签名的任何方法。 它允许方法作为参数传递&#xff0c;并允许事件驱动编程。它们提供了一种以类型安全的方…...

《机器学习》——数据标准化(0~1标准化,z标准化)

文章目录 数据标准化一、什么是标准化二、常用标准化0~1标准化z标准化 三、注意事项 数据标准化 一、什么是标准化 数据标准化是一种数据预处理技术&#xff0c;用于将数据按照一定的规则进行变换&#xff0c;使得不同特征或变量具有可比性和一致性。作用 消除量纲影响 在实际…...

如何监控和管理API接口的调用频率和并发量?

使用监控工具 APM&#xff08;应用性能管理&#xff09;工具 功能介绍&#xff1a;APM 工具如 New Relic、AppDynamics 等可以深入监控 API 的性能指标&#xff0c;包括调用频率、并发量、响应时间等。它们通过在应用程序中嵌入代理或使用无侵入式的监测方式&#xff0c;收集和…...

springboot+vue使用EasyCaptcha实现简单验证码

一、实现效果 springboot使用EasyCaptcha实现简单验证码&#xff0c;更多api和用法可以去github上查看EasyCaptcha: Java图形验证码&#xff0c;支持gif、中文、算术等类型&#xff0c;可用于Java Web、JavaSE等项目。 二、实现步骤 1、导入依赖 <!-- easy-captcha --&g…...

“善弈者”也需妙手,Oclean欧可林:差异化不是说说而已

作者 | 曾响铃 文 | 响铃说 俗话说&#xff0c;“牙痛不是病&#xff0c;痛起来要人命”。这话意思大家都知道&#xff0c;牙痛虽不是什么大病&#xff0c;可一旦发作却是极难忍受。 前几日&#xff0c;Oclean欧可林举办了一场AirPump A10氧气啵啵冲牙器新品品鉴会&#xff…...

Lianwei 安全周报|2025.1.2

以下是本周「Lianwei周报」&#xff0c;我们总结推荐了本周的政策/标准/指南最新动态、热点资讯和安全事件&#xff0c;保证大家不错过本周的每一个重点&#xff01; 政策/标准/指南最新动态 01 国家数据局等五部门印发《关于促进企业数据资源开发利用的意见》 为充分释放企业…...

吐卡机开发——指令合集—未来之窗行业应用跨平台架构

序号指令10A 09 02 01 01 0D DE20A 09 02 02 01 FD DE30A 09 02 03 01 6D DF40A 09 02 04 01 5D DD50A 09 02 05 01 CD DC60A 09 02 06 01 3D DC70A 09 02 07 01 AD DD80A 09 02 08 01 5D D890A 09 02 09 01 CD D9100A 09 02 10 01 5D D2110A 09 02 11 01 CD D3120A 09 02 12 0…...

C# 设计模式(创建型模式):单例模式

C# 设计模式&#xff08;创建型模式&#xff09;&#xff1a;单例模式 1. 引言 在软件开发中&#xff0c;设计模式是解决常见问题的经典方法。单例模式&#xff08;Singleton Pattern&#xff09;是创建型设计模式中的一种&#xff0c;旨在确保某个类只有一个实例&#xff0c…...

使用WebSocket 获取实时数据

回车发送数据&#xff0c;模拟服务器发送数据 效果图&#xff1a; 源码&#xff1a; <template><div><h1>WebSocket 实时数据</h1><input type"text" v-model"ipt" keyup.enter"sendMessage(ipt)"><div v-if…...

阿里云服务器上安装配置Logtail日志收集客户端

在当今的云计算时代,有效的日志管理对于监控、故障排查和性能优化至关重要。作为阿里云用户,您可以利用阿里云强大的日志服务(SLS)来管理您的日志。而Logtail,作为SLS的核心组件之一,在日志收集和传输中扮演着关键角色。本文将为您详细介绍如何在阿里云服务器上安装和配置…...

Java实现下载excel模板,并实现自定义下拉框

GetMapping("excel/download")ApiOperation(value "模板下载")public void getUserRecordTemplate(HttpServletResponse response, HttpServletRequest request) throws IOException {OutputStream outputStream response.getOutputStream();InputStream…...

postgres docker安装

mkdir -p /root/postgresql/data docker pull postgres:14 docker run --privilegedtrue --name postgres -e POSTGRES_PASSWORD123456 -e ALLOW_IP_RANGE0.0.0.0/0 -p 5432:5432 -v /root/postgresql/data:/var/lib/postgresql/data -d postgres:14#地址&#xff1a;192.168.3…...

数据库原理与应用期末复习

目录 第 1 章 概述 第 2 章 关系模型的基本概念 第 3 章 SQL 语言 第 4 章 中级 SQL 第 5 章 高级 SQL 第 6 章 关系代数语言 第 7 章 数据库设计和 ER 模型 第 8 章 关系数据库设计 第 13 章 事务 第 14 章 并发控制与恢复 第 1 章 概述 Database-management system…...

数据库知识汇总2

一. 范式 定义&#xff1a;范式是符合某一种级别的关系模式的集合。 关系数据库中的关系必须满足一定的要求。满足不同程度要求的为不同范式&#xff1b; 一个低一级范式的关系模式&#xff0c;通过模式分解&#xff08;schema decomposition&#xff09;可以转换为若干个高一…...

CS·GO搬砖流程详细版

说简单点&#xff0c;就是Steam买了然后BUFF上卖&#xff0c;或许大家都知道这点&#xff0c;但就是一些操作和细节问题没那么明白。我相信&#xff0c;你看完这篇文章以后&#xff0c;至少会有新的认知。 好吧&#xff0c;废话少说&#xff0c;直接上实操&#xff01; 首先准…...

《长寿养生报》是科普报刊吗?参与评选的科普作品需要注意什么?

随着各地医师职称评选标准改革的推广&#xff0c;目前不少省份已经将发表“科普作品”视作参与参与职称评选的工作成果。这一改革&#xff0c;也让《长寿养生报》这类报刊受到不少医护工作者的青睐。 《长寿养生报》是科普报刊吗&#xff1f;参与评选的科普作品需要注意什么&am…...

React native 原生环境搭建(最新版本RN环境搭建,不是expo)

前言 React Native 是 Facebook 推出的一款用于开发移动应用的框架&#xff0c;开发者可以用 JavaScript 和 React 等技术&#xff0c;一次编写代码&#xff0c;然后同时部署到 iOS 和 Android 平台上&#xff0c;大大节省了开发时间和人力成本&#xff0c;避免了为每个平台单…...

Unity Excel转Json编辑器工具

功能说明&#xff1a;根据 .xlsx 文件生成对应的 JSON 文件&#xff0c;并自动创建脚本 注意事项 Excel 读取依赖 本功能依赖 EPPlus 库&#xff0c;只能读取 .xlsx 文件。请确保将该脚本放置在 Assets 目录下的 Editor 文件夹中。同时&#xff0c;在 Editor 下再创建一个 Exc…...

XML结构快捷转JSON结构API集成指南

XML结构快捷转JSON结构API集成指南 引言 在当今的软件开发世界中&#xff0c;数据交换格式的选择对于系统的互操作性和效率至关重要。JSON&#xff08;JavaScript Object Notation&#xff09;和XML&#xff08;eXtensible Markup Language&#xff09;是两种广泛使用的数据表…...

数据挖掘——支持向量机分类器

数据挖掘——支持向量机分类器 支持向量机最小间隔面推导基于软间隔的C-SVM非线性SVM与核变换常用核函数 支持向量机 根据统计学习理论&#xff0c;学习机器的实际风险由经验风险值和置信范围值两部分组成。而基于经验风险最小化准则的学习方法只强调了训练样本的经验风险最小…...

ImageNet 2.0?自动驾驶数据集迎来自动标注新时代

引言&#xff1a; 3DGS因其渲染速度快和高质量的新视角合成而备受关注。一些研究人员尝试将3DGS应用于驾驶场景的重建。然而&#xff0c;这些方法通常依赖于多种数据类型&#xff0c;如深度图、3D框和移动物体的轨迹。此外&#xff0c;合成图像缺乏标注也限制了其在下游任务中的…...

智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之11 方案再探之2 项目文件(修改稿1)

(以下内容是第二次重建项目&#xff08;“方案再探”&#xff09;时的项目附件。) 为AI聊天工具添加一个知识系统 Part1 人性化&去中心化 前情提要 这一次我们暂时抛开前面对“智能工厂的软件设计”的考虑--其软件智能 产品就是 应用程序。直接将这些思维方式和方法论 运…...

详解MySQL SQL删除(超详,7K,含实例与分析)

文章目录 前言1. 删除表中的所有记录基本语法使用场景注意事项运用实例分析说明2. 删除特定记录基本语法使用场景注意事项运用实例分析说明3. 删除单条记录基本语法使用场景注意事项运用实例分析说明4. 删除违反引用完整性的记录基本语法使用场景注意事项运用实例分析说明5. 删…...

uniapp:跳转第三方地图

1.跳转第三方高德地图 //跳转地图 toMap(item){uni.navigateTo({url: (window.location.href https://uri.amap.com/navigation?to${item.lng},${item.lat},${item.shopName}&modecar&policy1&srchttps://gawl.gazhcs.com/wap/index.html&callnative0)}) },…...

深入浅出梯度下降算法:快速抵达函数最小值的方法

引言 梯度是机器学习和优化领域中不可或缺的概念&#xff0c;它为我们提供了理解和调整多维空间中函数行为的工具。本文将详细介绍梯度的定义、性质&#xff0c;并通过具体的一元和多元函数案例展示如何使用梯度下降算法找到最佳参数。 一、梯度的基础知识 1.1 定义与计算 梯…...

RWKV 语言模型

RWKV Language Model是一种独特的循环神经网络&#xff08;RNN&#xff09;架构的语言模型&#xff0c;具有诸多优势和特点&#xff0c;在自然语言处理领域展现出了良好的性能和应用潜力&#xff0c;以下是具体介绍&#xff1a; 核心原理 融合RNN与Transformer优点&#xff1a;…...

pycharm如何拉取一个git项目,然后,修改后再上传到自建的项目中?

以chattts为例 https://github.com/2noise/ChatTTS.git 1.建一个虚拟环境&#xff0c;用于项目使用 2.pychar&#xff4d;新建工程 &#xff13;.忽略 提示 勾选&#xff0c;新建远程仓库 设置账号和密码 设置git路径&#xff0c;一般是正确的&#xff0c;点测试即可 &…...

Java 性能调优实战

性能调优是每个程序员在开发过程中都无法避免的课题&#xff0c;尤其在面对大规模、高并发的系统时&#xff0c;性能优化更是必不可少。本文将根据《Java 性能调优实战》课程的七个模块&#xff0c;深入探讨其中的核心内容&#xff0c;结合实际代码示例&#xff0c;帮助大家更好…...

ctfshow 每日练习 web 区 php特性 1-10

前置知识 这个php特性可以很好的练习我们的白盒简单代码的审计能力 web89 preg_match 正则匹配函数 &#xff08;绕过 &#xff1a; 换行符绕过 &#xff08;也可以利用他的数组返回数字进行绕过一下禁止字符的情况&#xff09;&#xff09; include("flag.php&q…...

《C++设计模式》单例模式

文章目录 1、简介2、单例模式的种类2.1 饿汉式单例模式&#xff1a;2.2 懒汉式单例模式&#xff1a; 3、单例模式的具体介绍3.1、饿汉式3.1.1、代码示例3.1.2、组成部分3.1.3、优缺点3.1.4、应用场景 3.2、懒汉式3.2.1、代码示例3.2.2、组成部分3.2.3、优缺点3.2.4、应用场景 4…...