全面解析:C# 委托的实质性应用与优势

有人问C#的委托(Delegate)有什么实质性用途?委托在C#其实是无处不在,那么它具体用在那里呢?。

本文将从委托(Delegate)定义和演变讲起,让大家一目了然。

C#的委托(Delegate)是强类型的函数指针,用于引用方法并允许将方法作为参数传递。随着C#的演变,委托的功能和用途变得越来越强大和灵活。

本文将从C#委托的演变谈起,详细介绍其实质性用途,并通过代码实例加以证明。

委托的演变

C# 1.0: 基本委托

在C# 1.0中,引入了基本的委托概念,使得方法可以作为对象传递。这是实现事件和回调机制的基础。

using System;  public delegate void Notify();  // 声明委托  public class ProcessBusinessLogic  
{  public event Notify ProcessCompleted;  // 使用委托声明事件  public void StartProcess()  {  Console.WriteLine("Process Started!");  // 模拟一些处理任务  System.Threading.Thread.Sleep(3000);  // 处理完成后触发事件  OnProcessCompleted();  }  protected virtual void OnProcessCompleted()  {  ProcessCompleted?.Invoke();  }  
}  class Program  
{  static void Main(string[] args)  {  ProcessBusinessLogic bl = new ProcessBusinessLogic();  bl.ProcessCompleted += Bl_ProcessCompleted;  // 订阅事件  bl.StartProcess();  }  private static void Bl_ProcessCompleted()  {  Console.WriteLine("Process Completed!");  }  
}  
C# 2.0: 匿名方法

C# 2.0引入了匿名方法,使得委托的使用更加灵活,不需要单独定义方法即可实现回调。

using System;  public delegate void Print(int value);  public class Program  
{  public static void Main(string[] args)  {  Print print = delegate(int val) {  Console.WriteLine("Anonymous method: {0}", val);  };  print(100);  }  
}  
C# 3.0: Lambda表达式

C# 3.0进一步引入了Lambda表达式,简化了委托的语法,使得代码更加简洁和易读。

using System;  public delegate void Print(int value);  public class Program  
{  public static void Main(string[] args)  {  Print print = (val) => Console.WriteLine("Lambda expression: {0}", val);  print(200);  }  
}  
C# 4.0及以后: 泛型委托和内置委托类型

随着C#的不断发展,泛型委托和内置委托类型(如ActionFuncPredicate)被引入,进一步增强了委托的功能和灵活性。

using System;  public class Program  
{  public static void Main(string[] args)  {  Action<int> print = val => Console.WriteLine("Action delegate: {0}", val);  print(300);  Func<int, int> square = x => x * x;  Console.WriteLine("Func delegate: {0}", square(5));  Predicate<int> isPositive = x => x > 0;  Console.WriteLine("Predicate delegate: {0}", isPositive(10));  }  
}  

委托的实质性用途

1、简单回调机制

在编写需要回调功能的代码时,委托可以扮演重要角色。例如,当一个方法完成某项任务时,可以通过回调通知调用者。

using System;  public delegate void Notify();  // 声明委托  public class ProcessBusinessLogic  
{  public event Notify ProcessCompleted;  // 使用委托声明事件  public void StartProcess()  {  Console.WriteLine("Process Started!");  // 模拟一些处理任务  System.Threading.Thread.Sleep(3000);  // 处理完成后触发事件  OnProcessCompleted();  }  protected virtual void OnProcessCompleted()  {  ProcessCompleted?.Invoke();  }  
}  class Program  
{  static void Main(string[] args)  {  ProcessBusinessLogic bl = new ProcessBusinessLogic();  bl.ProcessCompleted += Bl_ProcessCompleted;  // 订阅事件  bl.StartProcess();  }  private static void Bl_ProcessCompleted()  {  Console.WriteLine("Process Completed!");  }  
}  

在这个例子中,当StartProcess方法执行完毕时,会通过委托Notify通知订阅者。

2、多播委托

多播委托可以引用多个方法,并且在调用时按顺序调用这些方法。这对于需要依次执行多个处理的场景非常有用。

using System;  public delegate void Notify();  // 声明委托  public class Program  
{  public static void Main(string[] args)  {  Notify notify = Method1;  notify += Method2;  // 订阅多个方法  notify();  }  public static void Method1()  {  Console.WriteLine("Method1 invoked.");  }  public static void Method2()  {  Console.WriteLine("Method2 invoked.");  }  
}  

在这个例子中,notify委托依次调用Method1Method2

3、匿名方法和Lambda表达式

委托可以结合匿名方法和Lambda表达式使用,使代码更加简洁和灵活。

using System;  public delegate void Print(int value);  public class Program  
{  public static void Main(string[] args)  {  Print print = delegate(int val) {  Console.WriteLine("Anonymous method: {0}", val);  };  print(100);  print = (val) => Console.WriteLine("Lambda expression: {0}", val);  print(200);  }  
}  

在这个例子中,使用匿名方法和Lambda表达式定义委托的实现方式,使代码更加简洁。

4、事件处理

委托是事件处理的基础,通过委托可以实现事件的定义和处理。例如,在用户界面编程中,按钮的点击事件处理。

using System;  public class Button  
{  public delegate void ClickHandler(object sender, EventArgs e);  public event ClickHandler Click;  public void OnClick(EventArgs e)  {  Click?.Invoke(this, e);  }  
}  public class Program  
{  public static void Main(string[] args)  {  Button button = new Button();  button.Click += Button_Click;  button.OnClick(EventArgs.Empty);  }  private static void Button_Click(object sender, EventArgs e)  {  Console.WriteLine("Button clicked!");  }  
}  

在这个例子中,Button类定义了Click事件,通过委托ClickHandler处理点击事件。

5、函数式编程

委托允许将函数作为对象处理,使得C#能够支持一定程度的函数式编程。例如,LINQ(Language Integrated Query)大量使用了委托和Lambda表达式。

using System;  
using System.Linq;  
using System.Collections.Generic;  public class Program  
{  public static void Main(string[] args)  {  List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };  List<int> evenNumbers = numbers.Where(n => n % 2 == 0).ToList();  evenNumbers.ForEach(n => Console.WriteLine(n));  }  
}  

在这个例子中,Where方法接受一个委托Func<int, bool>来筛选列表中的偶数。

总结

C#的委托从基本概念到匿名方法,再到Lambda表达式和泛型委托,其演变展示了语言的强大和灵活。

委托在回调、多播、事件处理以及函数式编程中的广泛应用,极大地增强了C#的功能和代码可维护性。

通过本文的示例,可以清晰地看到委托的实质性用途和在现代编程中的重要地位。

希望本文对大家有所收获,大家对委托有什么看法,欢迎留言讨论。

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

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

相关文章

【学习笔记】Elastic-Job和Quartz 实现企业级定时任务

Elastic-Job和Quartz 实现企业级定时任务 知识拆解框架整合Java高级玩法定时任务案例 第1章 课程介绍 课程的总体介绍&#xff0c;定时任务的应用场景和发展趋势&#xff0c;以及分布式走时任务的介绍 1-1、导学 1-2、为什么学习定时任务 1-3、定时任务技术发展趋势 1-4、主…

成为AIGC人才,是职场人当下的必修课?

随着科技的飞速进步&#xff0c;人工智能和机器学习技术正逐渐渗透到我们生活的每一个角落&#xff0c;其中&#xff0c;人工智能生成内容&#xff08;AIGC&#xff09;更是以其独特的魅力和广泛的应用前景&#xff0c;成为当下科技领域的热门话题。在这样的背景下&#xff0c;…

Matlab个性化绘图第3期—带三维球标记的折线图

前段时间有会员在群里问该如何绘制下面这种带三维球标记的折线图&#xff1a; 本期内容就来分享一下带三维球标记的折线图的Matlab绘制思路。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&#xff0c;加群的朋友请自行下载。有需…

【Android面试八股文】你能详细讲讲你在APK瘦身方面都做了哪些工作吗?

文章目录 一、我用到过的方法二、扩展阅读 其他的大厂方案一、我用到过的方法 面试官: 你能详细讲讲你在APK瘦身方面都做了哪些工作吗? 你: 在过去的项目中,我做了多方面的优化来减少APK的大小,从而提升应用的下载速度和安装体验。以下是一些具体的措施和技术实现: 移除不…

JavaScript的学习之旅(6.20)

目录 一、认识三个常见的js代码 二、js写入的第二种方式 三、js里内外部文件 一、认识三个常见的js代码 <script>//写入js位置的第一个地方// 控制浏览器弹出一个警告框alert("这是一个警告");// 在计算机页面输入一个内容&#xff08;写入body中&#xff…

使用PlugLink实现自动化运营:提升效率的秘密武器(附源码)

使用PlugLink实现自动化运营&#xff1a;提升效率的秘密武器 作为一款开源的自动化工具&#xff0c;PlugLink可以帮助个人和小微企业实现运营自动化&#xff0c;极大地提升工作效率&#xff0c;降低运营成本。 一、PlugLink简介 PlugLink是一个基于Python的开源自动化工具框…

候选键的确定方法-如何判断属性集U的子集K是否为候选键、如何找到关系模式的候选键

一、候选键的定义 在关系模式R(U,F)中&#xff0c;若&#xff0c;且K满足&#xff0c;则K为关系模式R的候选键 关系模式R的候选键必须满足以下两个条件&#xff1a; &#xff08;1&#xff09;必须是属性集U的子集 &#xff08;2&#xff09;完全函数决定属性集U 二、如何…

易兆微电子_嵌入式软件工程师笔试题

易先电子 嵌入式软件工程师笔试题(十七) 1.关键字 extern是什么含义, 请举例说明。 修饰符extern用在变量或者函数的声明前&#xff0c;用来说明 “ 此变量 / 函数是在别处定义的&#xff0c;要在此处引用 ”。 //main.c #include <stdio.h>int main() {extern int num…

OS复习笔记ch11-2

上一节我们学习的内容是I/O系统的特点和设备分类和差异&#xff0c;这一节我们将主要关注I/O控制方式、OS设计问题、I/O逻辑结构等。 I/O功能的演变 在专栏的ch1-2中&#xff0c;我们详细讲解了CPU与外设的三种交互方式&#xff0c;这里简单地带过。 &#xff08;1&#xff0…

使用KMP算法实现对于指定两个字符之间的字符串分割方法

import java.util.ArrayList;public class UsingKMPAlgorithmSpiltString {public static void main(String[] args) {//待分割的文本String text = "【分割符号】劳力士【分割符号】浪琴【分割符号】欧米茄【分割符号】宝珀【分割符号】百达翡丽" ;//分割符号字符串…

集合进阶(泛型、泛型通配符、数据结构(二叉树、平衡二叉树、红黑树

一、泛型类、泛型方法、泛型接口 1、泛型概述 泛型&#xff1a;是JDK5中引入的特性&#xff0c;可以在编译阶段约束操作的数据类型&#xff0c;并进行检查。泛型的格式&#xff1a;<数据类型>注意&#xff1a;泛型只能支持引用数据类型。 泛型的好处 1、统一数据类型。 …

docker 指令 初级入门

Docker是一种开源的应用容器引擎&#xff0c;基于Go语言开发并遵循Apache2.0协议开源。它能够让开发者将应用及其依赖打包到一个轻量级的、可移植的容器中&#xff0c;然后发布到任何支持Docker的平台上。Docker命令是操作Docker的主要方式&#xff0c;对于Docker的初学者来说&…

上位机图像处理和嵌入式模块部署(h750 mcu串口命令处理)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面学习103和407的时候&#xff0c;当时学过串口的收发。不过当时使用的主要是阻塞的方式。这一次&#xff0c;我们看下应该怎么利用中断的形式进…

【UE5.1】制作自己的载具

目录 前言 效果 步骤 一、制作载具模型 二、载具设置 三、控制载具 四、方向盘旋转 前言 在前面我们通过UE4完成了载具的制作&#xff0c;下面我们介绍一下如何通过UE5制作载具。 效果 步骤 一、制作载具模型 制作方法同【UE4 制作自己的载具】1-使用3dsmax制作载具…

PhotoShop批量生成存储jpg

1、说明 根据之前自动批量生成psd格式的文件。打印一般都是jpg格式的&#xff0c;那如果将这些psd的文件&#xff0c;生成jpg&#xff0c;本文采用ps的动作 2、生成动作 点击窗口-动作 录屏存储jpg动作 3、根据动作生成 选择相应动作之后选择需要处理的文件夹

Java面试八股之JVM永久代会发生垃圾回收吗

JVM永久代会发生垃圾回收吗 JVM的永久代&#xff08;PermGen&#xff09;在Java 8之前是存在的一部分&#xff0c;主要用于存储类的元数据、常量池、静态变量等。在这些版本中&#xff0c;永久代确实会发生垃圾回收&#xff0c;尤其是在永久代空间不足或超过某个阈值时&#x…

c#考试知识点

第一题 //数组{1&#xff0c;2&#xff0c;3&#xff0c;&#xff0c;8&#xff0c;6} //方法&#xff08;数组&#xff0c;目标值&#xff09; //输出 //接收一个数组&#xff0c;输出目标值是数组中哪两个数的和&#xff0c;并输出下标 using System; using System.Collectio…

大数据智能化教学解决方案

引言 在信息化浪潮的推动下&#xff0c;大数据与人工智能已成为推动社会进步的重要力量。作为国家战略新兴产业&#xff0c;大数据智能化的发展对于培养具备创新精神和实践能力的高素质人才提出了迫切需求。唯众紧跟时代步伐&#xff0c;针对大数据智能化人才培养的痛点与难点…

企业该如何防查盗版?如何防软件后台泄密数据?

随着信息化的发展&#xff0c;企业日常办公越来越依赖互联网。终端以及普通PC终端在访问互联网过程中&#xff0c;会遇到各种各样不容忽视的风险&#xff0c;例如员工主动故意的数据泄漏&#xff0c;后台应用程序偷偷向外部发信息&#xff0c;木马间谍软件的外联&#xff0c;以…

websocket nignx 配置

server { location /wss { proxy_pass http://127.0.0.1:8282; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection “Upgrade”; proxy_set_header X-Real-IP $remote_addr; } listen 443; location / {} 站点的其它配置… }