C# 委托与匿名方法

文章目录

  • 1.委托的基本概念
    • 1.1 声明和使用委托
    • 1.2 委托的创建与调用
    • 1.3 委托的多播功能
  • 2. 委托的应用场景
    • 2.1 事件处理
    • 2.2 回调函数
    • 2.3 策略模式
  • 3.匿名方法
    • 3.1 定义匿名方法
    • 3.2 匿名方法的应用
  • 4.委托与匿名方法的实际应用示例
    • 4.1 使用委托实现回调函数
    • 4.2 使用匿名方法实现事件处理
    • 4.3 使用匿名方法作为回调
  • 5.委托与匿名方法的注意事项
    • 5.1 委托的类型安全
    • 5.2 委托的生命周期
    • 5.3 匿名方法的作用域

1.委托的基本概念

委托是一种引用类型,可以用来封装一个或多个方法,适合用于事件处理和回调的场景。委托的声明形式类似于方法签名,但它不是方法,而是方法的引用。

1.1 声明和使用委托

在 C# 中定义委托的语法如下:
    delegate 返回类型 委托名(参数列表);
例如,定义一个返回 int、接收两个 int 参数的委托:

delegate int MathOperation(int a, int b);

1.2 委托的创建与调用

    创建委托实例时,可以将一个符合签名的方法赋给它。以下是一个委托的基本使用示例:

using System;class Program
{// 定义委托delegate int MathOperation(int a, int b);// 定义符合委托签名的方法static int Add(int x, int y) => x + y;static int Multiply(int x, int y) => x * y;static void Main(){// 创建委托实例,并传入方法MathOperation addOperation = Add;MathOperation multiplyOperation = Multiply;// 调用委托Console.WriteLine(addOperation(3, 4));       // 输出: 7Console.WriteLine(multiplyOperation(3, 4));  // 输出: 12}
}

    MathOperation 委托可以引用任意符合 int (int, int) 签名的方法。

1.3 委托的多播功能

    委托还可以引用多个方法,这种特性被称为多播委托(Multicast Delegate)。可以通过 += 运算符将多个方法绑定到一个委托实例上,执行时会按顺序依次调用这些方法。

using System;class Program
{delegate void PrintMessage();static void Hello() => Console.WriteLine("Hello");static void World() => Console.WriteLine("World");static void Main(){PrintMessage message = Hello;message += World;message();  // 输出: Hello \n World}
}

在调用 message() 时,Hello 和 World 方法都会被依次调用。

2. 委托的应用场景

2.1 事件处理

    在 GUI 编程中,用户操作(如点击按钮)会触发事件。事件处理器通常使用委托进行实现,允许动态绑定处理方法。

2.2 回调函数

    在异步编程或长时间运行的任务中,回调函数非常有用。我们可以将回调函数定义为委托,以便任务完成后调用。

2.3 策略模式

    在设计模式中,策略模式允许我们在运行时动态选择算法。可以通过委托实现不同的算法,并在需要时进行切换。

3.匿名方法

    在 C# 2.0 及以上版本中,匿名方法 为委托提供了更加简洁的语法。匿名方法是一种不需要命名的方法,可以在创建委托实例时直接定义,减少代码量。

3.1 定义匿名方法

    匿名方法的语法是在 delegate 关键字后直接提供方法实现,而不需要方法名。

using System;class Program
{delegate void Greet(string name);static void Main(){Greet greet = delegate (string name){Console.WriteLine("Hello, " + name);};greet("Alice");  // 输出: Hello, Alice}
}

匿名方法 delegate (string name) { … } 实现了 Greet 委托所需的方法签名。

3.2 匿名方法的应用

  • 事件处理:为事件动态绑定方法。
  • 回调函数:实现简单的回调逻辑。
  • LINQ 查询:匿名方法在 LINQ 表达式中很常见。

4.委托与匿名方法的实际应用示例

4.1 使用委托实现回调函数

    假设我们有一个执行某种操作的长时间任务,任务完成后希望调用回调函数,可以使用委托实现。

using System;
using System.Threading;class Program
{// 定义回调委托delegate void TaskCompletedCallback(string message);static void Main(){// 传递回调方法作为参数PerformTask("Sample Task", TaskCompleted);}static void PerformTask(string taskName, TaskCompletedCallback callback){Console.WriteLine($"Starting {taskName}...");Thread.Sleep(2000);  // 模拟耗时操作// 任务完成后调用回调callback($"{taskName} completed successfully.");}static void TaskCompleted(string message){Console.WriteLine(message);}
}

在上述示例中,当 PerformTask 完成时会调用 TaskCompleted 方法,输出任务完成消息。

4.2 使用匿名方法实现事件处理

    在事件处理中,匿名方法可以使代码更加简洁。例如,创建一个按钮点击事件的处理器:

using System;
using System.Windows.Forms;class Program
{static void Main(){Button button = new Button();button.Text = "Click Me";// 使用匿名方法绑定事件处理器button.Click += delegate (object sender, EventArgs e){Console.WriteLine("Button clicked!");};Application.Run(new Form { Controls = { button } });}
}

在该例子中,button.Click 事件使用匿名方法直接定义了事件处理逻辑,无需创建单独的方法。

4.3 使用匿名方法作为回调

    在需要临时回调逻辑的场景下,匿名方法可以简化代码结构。以下是一个简单的计时器回调示例:

using System;
using System.Timers;class Program
{static void Main(){Timer timer = new Timer(1000);// 使用匿名方法定义回调timer.Elapsed += delegate (object sender, ElapsedEventArgs e){Console.WriteLine("Timer ticked at: " + e.SignalTime);};timer.Start();Console.ReadLine();timer.Stop();}
}

timer.Elapsed 事件使用匿名方法实现,简化了代码逻辑。

5.委托与匿名方法的注意事项

5.1 委托的类型安全

    委托类型必须与它引用的方法完全匹配,包括返回类型和参数列表,否则会导致编译错误。因此,定义委托时需要确保签名的一致性。

5.2 委托的生命周期

    在多播委托中,委托引用的多个方法顺序执行。如果在多播委托执行过程中发生异常,后续方法不会继续执行。因此,在实现多播委托时,需考虑异常处理的问题。

5.3 匿名方法的作用域

    匿名方法可以访问其声明作用域中的变量,允许捕获局部变量。这种特性在某些情况下会产生闭包(Closure)现象。需要注意,捕获的变量在委托生命周期内始终保持引用,因此可能导致预期外的行为。

using System;
using System.Collections.Generic;class Program
{static void Main(){List<Action> actions = new List<Action>();for (int i = 0; i < 3; i++){actions.Add(delegate { Console.WriteLine(i); });}foreach (var action in actions){action();  // 输出的值可能不符合预期,因为 i 是引用捕获}}
}

由于匿名方法捕获了 i 的引用,而不是值,因此最后输出的都是循环结束后的 i 值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/470525.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Wireshark

目录 解题思路 题目设计原理 总结 解题思路 首先下载文件&#xff0c;用 wireshark 打开一头雾水。 但是看看题目的提示&#xff0c;说管理员的密码就是 flag 的内容&#xff0c;我们可以知道&#xff0c;关键词估计是密码&#xff0c;passwd、password、pwd之类的。 所以我…

FreeRTOS学习13——任务相关API函数

任务相关API函数 任务相关API函数任务相关API函数介绍任务相关 API 函数详解函数 uxTaskPriorityGet()函数 vTaskPrioritySet()函数 uxTaskGetSystemState()函数 vTaskGetInfo()函数 xTaskGetApplicationTaskTag()函数 xTaskGetCurrentHandle()函数 xTaskGetHandle()函数 xTask…

使用kalibr_calibration标定相机(realsense)和imu(h7min)

vslam-evaluation/VINS/Installation documentation/4.IMU和相机联合标定kalibr_calibration.md at master DroidAITech/vslam-evaluation GitHub 目录 1.kalibr安装 1.1安装依赖项 1.2创建工作空间 1.3下载kalibr并编译 1.4设置环境变量 2.准备标定板 3.配置驱动和打…

[Docker#8] 容器配置 | Mysql | Redis | C++ | 资源控制 | 命令对比

目录 一&#xff1a;Mysql 容器化安装 二&#xff1a;Redis 容器化安装 Redis 简介 Redis 容器创建 三&#xff1a;C容器制作 四&#xff1a;容器资源更新 常见问题 一&#xff1a;Mysql 容器化安装 进入 mysql 的镜像网站&#xff0c;查找 mysql 的镜像 mysql docker…

1小时构建Vue3知识体系之vue的生命周期函数

本文转载自&#xff1a;https://fangcaicoding.cn/course/12/63 大家好&#xff01;我是方才&#xff0c;目前是8人后端研发团队的负责人&#xff0c;拥有6年后端经验&3年团队管理经验。 系统学习践行者&#xff01;近期在系统化输出前端入门相关技术文章&#xff0c;期望能…

数据结构-集合

一.集合的表示 一个重要的操作是查某个元素属于哪个集合&#xff0c;另一个操作是合并操作 从这个树的节点去找树根也就是从下往上找,要把树并起来只需把两个根并在一起就可以了 不存在已知一个节点去找孩子节点&#xff0c;根重要的是已知一个节点找它的父亲节点,与之前的二…

unity基础,点乘叉乘。

简单记录下点乘叉乘&#xff0c;要不每次用完就忘&#xff0c;忘了又查。 using System.Collections; using System.Collections.Generic; using UnityEngine;public class TestCrossDot : MonoBehaviour {/// <summary>/// 原点/// </summary>public Transform t…

springboot 之 整合springdoc2.6 (swagger 3)

版本 springboot 3.3.5 jdk 17 springdoc 2.6.0 依赖pom <dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.6.0</version> </dependency>注解对比…

数据结构与算法-前缀和数组

前缀和问题 什么是前缀和? 对于一个一般数组 nums,如果我们需要知道 S1 nums[0] nums[1]的结果&#xff0c; S2 nums[0] nums[1] nums[2] … 计算公式相当于: S2 S1 nums[2] … Sn Sn-1 nums[n]; 所谓前缀和&#xff1a;用来记录数组前项和的一个新数组&#xff0c;提…

R语言机器学习与临床预测模型77--机器学习预测常用R语言包

R小盐准备介绍R语言机器学习与预测模型的学习笔记 你想要的R语言学习资料都在这里&#xff0c; 快来收藏关注【科研私家菜】 01 预测模型常用R包 常见回归分析包: rpart 包含有分类回归树的方法; earth 包可以实现多元自适应样条回归; mgev包含广义加性模型回归; Rweka 包中的M…

Elasticsearch可视化工具Elasticvue插件用法

目录 1.打开浏览器扩展程序(示例Edge浏览器) ​2.搜索elasticvue并安装 3.打开elasticvue ​4.连接Es 5.有些浏览器无法下载安装扩展&#xff0c;例如谷歌。可以打包扩展给别的浏览器使用。 5.1打开浏览器扩展&#xff0c;打开开发人员模式&#xff0c;记住扩展程序id 5…

大数据技术之HBase中的HRegion

如果你正在学习大数据&#xff0c;你应该知道HBase是一个列式存储的NoSQL分布式数据库&#xff0c;可以配合Hadoop来使用。今天自己简单做了几页PPT&#xff0c;解释了一下HBase当中HRegion的基本概念&#xff0c;很多初学者在学习的时候对HRegion这个概念一直懵懵懂懂&#xf…

Spring Cloud Contract快速入门Demo

1.什么是Spring Cloud Contract &#xff1f; Spring Cloud Contract 是 Spring 提供的一套工具&#xff0c;用于帮助开发者通过契约&#xff08;Contract&#xff09;驱动的方式进行微服务的测试和集成。它主要解决微服务之间通信时&#xff0c;如何确保服务提供者和消费者之…

GISBox VS ArcGIS:分别适用于大型和小型项目的两款GIS软件

在现代地理信息系统&#xff08;GIS&#xff09;领域&#xff0c;有许多大家耳熟能详的GIS软件。它们各自具有独特的优势&#xff0c;适用于不同的行业需求和使用场景。在众多企业和开发者面前&#xff0c;如何选择合适的 GIS 软件成为了一个值得深入思考的问题。今天&#xff…

Linux 进程线程间通信总结

线程 线程共享存储空间主要带来的问题是数据同步和互斥。由于线程在同一进程中运行&#xff0c;它们共享相同的内存空间&#xff0c;任何线程都可以访问共享数据。这样&#xff0c;多个线程并发执行时&#xff0c;可能会导致以下两种主要问题&#xff1a; 互斥问题&#xff0…

【再谈设计模式】抽象工厂模式~对象创建的统筹者

一、引言 在软件开发的世界里&#xff0c;高效、灵活且易于维护的代码结构是每个开发者追求的目标。设计模式就像是建筑蓝图中的经典方案&#xff0c;为我们提供了应对各种常见问题的有效策略。其中&#xff0c;抽象工厂模式在对象创建方面扮演着重要的角色&#xff0c;它如同一…

Web安全之SQL注入---基础

文章目录 SQL注入简介SQL注入基础SQL注入分类SQL注入流程 SQL注入简介 什么是SQL注入&#xff1f; SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严&#xff0c;攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句&#xff0c;在管理…

机器学习——贝叶斯

&#x1f33a;历史文章列表&#x1f33a; 机器学习——损失函数、代价函数、KL散度机器学习——特征工程、正则化、强化学习机器学习——常见算法汇总机器学习——感知机、MLP、SVM机器学习——KNN机器学习——贝叶斯机器学习——决策树机器学习——随机森林、Bagging、Boostin…

gdb编译教程(支持linux下X86和ARM架构)

1、下载源码 http://ftp.gnu.org/gnu/gdb/ 我下载的8.2版本。 2、下载完后拷贝到linux的x86系统。 3、解压&#xff0c;然后进入到目录下&#xff0c;打开当前目录的命令行窗口。 4、创建一个生成目录。 5、我们先开始x86版本&#xff0c;这个比较简单&#xff0c;不需要配置…

10款翻译工具实践体验感受与解析!!!!!

在现今的数字化时代&#xff0c;翻译工具如同语言的桥梁&#xff0c;为我们打开了通向世界的大门。今天咱们不聊别的&#xff0c;就聊聊那些让我又爱不释手的翻译工具们。因为我的职业因素&#xff0c;作为一个经常需要跟各种语言打交道的“文字搬运工”&#xff0c;这些工具可…