委托

C# 委托简述 使用关键字delegate声明委托除了使用delegate定义 委托以外C#提供两个定义好的泛型委托Action与Func) (当然你也可以使用delegate自定义泛型委托)这里先介绍两个C#定义的委托,相信很多人都在使用,不管你清不清楚什么是委托Action:是无返回值的泛型委托。下面action 表示无参,无返回值的委托//定义委托action();//使用方式1//使用方式2Console.WriteLine("我是传入的无参无返回值的委托方法"); 阅读详情

委托的概念

委 托实际上是类(一个貌似函数一样的类),我们已经使用函数指针很多年了——函数指针也被称为过程类型,但是它们的实现都不是类。它们是单独的函数指针的简 单实例。委托是包含这些功能的类,委托类通过保留的列表来确定某些事物是否已经指派给了委托,这种算法可以理解为:“对于内部列表中的每一个回调函数,都 调用函数”。委托除了支持回调函数外,还可以通过该列表来实现多播(委托链)。

说白了,就是我们把一批具有相同特征的方法,通过建立与具有同样相同特征的委托的一个实例来进行传递,以使其它地方能对这些方法进行调用。即把方法当作参数进行传递(浅显的认识,勿笑)。

 

初识委托

示例1:

using System;

using System.Collections.Generic;

using System.Text;

using System.Web;

 

 

namespace MyDelegateTest

{

     /// <summary>

     /// 说明:一个简单的委托示例

     /// 作者:文野

     /// 联系:stwyhm.cnblogs.com

     /// </summary>

 

     // 新建一个用以输出消息的委托

     public delegate void WriteMessage();

    

     public class WriteToWeb

     {

         // 一个输出消息的静态方法

         public static void StaticWrite()

         {

              HttpContext.Current.Response.Write("委托调用了一个静态方法。<br />");

         }

 

         // 一个输出消息的类实例方法

         public void Write()

         {

              HttpContext.Current.Response.Write("委托调用了一个类实例方法。<br />");

         }

     }

}

调用:

protected void Page_Load(object sender, EventArgs e)

    {

         // 新建一个委托,回调函数是一个静态方法

         WriteMessage wm = new WriteMessage(WriteToWeb.StaticWrite);

 

         WriteToWeb w = new WriteToWeb();

         // 新建一个委托并与加到先前建立的委托组成委托链,回调函数是一个类实例方法

         wm += new WriteMessage(w.Write);

 

         // 执行委托链上所有的回调函数

         wm();

    }

 

上 面的示例程序首先建立了一个简单得不能再简单的用以输出的委托,下面的类中有两个与委托签名一致的方法(一个静态方法,一个类实例方法)。下面的调用过程 首先建立了一个使用回调静态方法的委托,其后又建立了一个使用类实例方法的委托并与先前的委托组成了一个委托链,最后执行委托链上所有的方法。

由此可见,委托最简单的理解就是利用与方法签名一致的委托,可以把方法当作参数一样来传递,无论是静态方法还是类实例方法。

 

委托的秘密


从上面的类视图中我们看到,对委托的定义最终被编译成一个类,这个类中定义有4种方法:构造器,Invoke,BeginInvoke,EndInvoke。

所有的委托都继承自MulticastDelegate,而MulticastDelegate又继续至Delegate。这样我们定义的委托自然也就继承了MulticastDelegate的字段、属性和方法。在继承得到的所有成员中,有3个最重要的字段:

1、_target:指向调用回调函数时应该操作的对象。该字段用于实例方法的回调。

2、_methodPtr:一个内部的整数值,CLR用它来识别回调的方法。

3、_prev:指向另一个委托对象。

当编译器知道我们在构造的是一个委托时,它会分析源代码来确定要引用哪个对象和方法。其中对象引用会被传递给_target(对于静态方法,_target被置为null),一个特殊的标识方法的Int32值会被传递给_methodPtr,_prev在构造器中被置为null,它被用于在委托链中记录下一个委托的引用。

每个委托对象实际上是对方法及其调用操作的一个包装,MulticastDelegate中定义了两个只读属性,Target和Method,Target(其实就是前面的_target字段)属性返回一个方法回调时操作的对象的引用,Method属性返回一个标识回调方法的System.Reflection.MethodInfo对象。

 

委托链

前面介绍过MulticastDelegate中有一个_prev的私有字段,这个字段指向另一个MulticastDelegate对象的引用,这样就实现了委托链(其实与我们在学链表时的实现方式是一致的)。

当委托链表被调用时,它首先会调用委托中在其前面的委托对象,这里如果被调的回调方法具有返回值,将被丢失,委托链只会返回最后一次调用回调方法的返回值。

 

委托示例

这是一个我自认为比较经典的委托示例(给排序算法传递一个动态比较的函数)。

 

using System;

using System.Collections.Generic;

using System.Text;

 

namespace MyDelegateTest

{

     /// <summary>

     /// 说明:给排序算法传递一个动态比较函数的委托示例

     /// 作者:文野

     /// 联系:stwyhm.cnblogs.com

     /// </summary>

    

     // 进行排序的委托

     public delegate bool Compare(int left, int right);

 

     public class DelegateSample

     {

         private int[] items;

 

         public int[] Items

         {

              set { items = value; }

              get { return items; }

         }

 

         // 比大

         public bool Greater(int left, int right)

         {

              return left > right;

         }

 

         // 比小

         public bool Less(int left, int right)

         {

              return !Greater(left, right);

         }

 

         public void Sort(Compare compare)

         {

              for (int i = 0; i < items.Length-1; i++)

              {

                   for (int j = i + 1; j < items.Length; j++)

                   {

                       if (compare(items[i], items[j]))

                       {

                            int tmp = items[i];

                            items[i] = items[j];

                            items[j] = tmp;

                       }

                   }

              }

         }

     }

}

 

调用页面

using System;

using System.Data;

using System.Configuration;

using System.Collections;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

 

using MyDelegateTest;

 

public partial class Sort : System.Web.UI.Page

{

     protected void Page_Load(object sender, EventArgs e)

     {

 

     }

     protected void Button1_Click(object sender, EventArgs e)

     {

         DelegateSample sample = new DelegateSample();

         sample.Items = GetItems();

 

         // 使用降序

         sample.Sort(new Compare(sample.Less));

 

         PrintItems(sample);

     }

 

     private void PrintItems(DelegateSample sample)

     {

         for (int i = 0; i < sample.Items.Length; i++)

         {

              Response.Write(sample.Items[i] + "<br/>");

         }

     }

 

     private int[] GetItems()

     {

         string[] str = this.TextBox1.Text.Split(",".ToCharArray());

         int[] items = new int[str.Length];

         for (int i = 0; i < str.Length; i++)

              items[i] = int.Parse(str[i]);

 

         return items;

     }

     protected void Button2_Click(object sender, EventArgs e)

     {

         DelegateSample sample = new DelegateSample();

         sample.Items = GetItems();

 

         // 使用升序

         sample.Sort(new Compare(sample.Greater));

 

         PrintItems(sample);

     }

}

 

效果图:

降序



升序


 

参考资料:

《.NET框架程序设计》

《Visual Basic .Net Power Coding》


委托(委托变量、多路委托变量) 微软公司在设计运行于.NET Framework 平台之上的面向对象语言(如C#和VisualBasic.NET)时引入了这一新特性。 int i; //定义变量 i=100; //给变量赋值 委托(delegate)也可以看成是一种数据类型,它所定义的变量能接收的数值只能是一个函数。委托类型的变量可以接收一个函数的地址,很类似于C++语言的函数指针。 public class M 阅读详情

相关推荐

离线安装PlutoSDR硬件支持包全攻略:没有MathWorks账号也能搞定MATLAB集成

本文详细介绍了在没有MathWorks账号和网络环境的情况下,如何离线安装PlutoSDR硬件支持包并实现MATLAB集成的完整解决方案。从驱动安装、设备识别到MATLAB支持包的离线部署,提供了全面的步骤指导和常见问题排查方法,特别适合高校实验室、军工单位等内网环境使用。

js777的博客 268

C# 委托详解

委托,委托的使用,多播委托,泛型委托

鲤籽鲲的博客 2万+

消费级显卡跑大模型:RTX 3060 12G 部署 70 亿参数 AI 编程助手的优化实战

本文详细介绍了如何在消费级显卡RTX 3060 12G上,通过量化、投机解码和分页KV-Cache等核心优化技术,成功部署并流畅运行70亿参数的CodeLlama-7B编程助手。文章提供了从环境配置、模型准备到参数调优的完整实战笔记,实测显存占用降至7.3GB,生成速度达21.7 token/秒,为开发者和技术爱好者提供了可行的本地AI部署方案。

weixin_29053067的博客 1262

C#之委托

C#中的委托是一个类型,它描述了一个方法的签名,即方法的参数类型和返回类型。委托可以看作是一个指向方法的引用,使得我们可以像使用函数指针一样调用这些方法。 将一个或多个方法作为参数传递给另一个方法,从而在需要时调用这些方法。 实现事件处理程序。 实现回调方法。 实现异步编程等功能。 委托和类一样,是一种用户定义类型。但类表示的是数据和方法的集合,而委托则持有一个或多个方法,以及一系列预定义操作。可以通过一下操作步骤来使用委托。

互联网底层民工的博客 1万+

HMC5883L磁力计在STM32F4上的I2C驱动与数据校准实战

本文详细介绍了HMC5883L磁力计在STM32F4平台上的I2C驱动开发与数据校准实战。通过解析寄存器配置、数据读取处理和椭圆拟合校准算法,帮助开发者实现精准的地磁测量,特别适用于无人机导航和机器人系统中的航向确定与陀螺仪漂移修正。

2y3u4i5o6p的博客 1038

用友U8自定义按钮开发:从基础配置到实战业务集成

本文详细介绍了用友U8自定义按钮开发的完整流程,从基础配置到实战业务集成。通过实际案例演示如何在U8系统中添加和替换功能按钮,包括数据库配置、SQL脚本编写和VB组件开发等关键技术点,帮助企业用户实现业务场景的深度定制。

weixin_29698641的博客 257

[UE4]委托代理:单播委托,多播委托,动态单播委托,动态多播委托,事件

注意:在声明动态多播委托(DECLARE_DYNAMIC_MULTICAST_DELEGATE)时,DelegateName 参数必须以字符 'F' 开头,否则编译无法通过。 最好时声明所有委托时,DelegateName参数都以字符 'F' 开头,这样就没有问题了。 报错参考如下: ...

iDaDi的博客 1万+

基于Python的高考志愿辅助填报系统

在实际应用中,系统需要处理更复杂的数据,包括更多的高校和专业信息、更详细的录取规则、以及用户的历史选择等。系统需要提供用户友好的界面,让考生输入自己的信息和偏好,然后通过后端的模型计算出推荐的志愿列表。此外,系统还应该提供一些个性化的服务,如根据考生的输入动态调整推荐策略、保存用户的填报历史和偏好等。特征可能包括考生的分数、所在省份、文理科类别、专业偏好、高校的地理位置、排名、专业的就业前景等。3. **推荐逻辑**:根据用户的分数和专业偏好,结合历史录取数据,使用简单的算法来推荐可能录取的高校和专业。

coder_wwwdy的博客 1978

kotlin委托:,委托属性,属性委托,委托类,Delegation,Delegated properties

Kotlin中的by关键字用于实现委托模式,主要分为两类:类/接口委托和属性委托。类委托通过by将接口实现委托给另一个对象,减少模板代码。属性委托则通过by将属性的读写操作委托给其他对象,支持多种标准委托方式: 属性转发:将属性委托给另一个属性,常用于字段重命名 懒加载:使用lazy实现首次访问时才初始化的特性 可观察属性:通过Delegates.observable监听属性变化 可否决变更:使用Delegates.vetoable拦截并决定是否接受新值 相比Java的手动委托,Kotlin的委托模式更简洁

Huang兄 1104

数据结构实验1.2—高精度计算PI值(西工大)

这是数据结构第二题的题目,是让我们根据用户的需求来计算派的值 这是题目的详细描述,刚看到这道题的时候,我是真的头大,完全没有思路,于是查找了一些大佬的笔记后才开始编写 这是我在写这些代码是所运用到的数学反三角函数幂次展开式的知识。 下面是正确的代码以及我的一些见解,和需要注意的一些地方。希望能对你有所帮助。如有更加精简的算法,请在评论区留下你的算法!!!谢谢!!! #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdl

abcdef0623的博客 5831

基于大模型最大化电力交易收益(策略与代码实践)

新一代电力交易系统正借助大型语言模型(LLM)实现智能化转型。面对可再生能源占比提升带来的市场波动性加剧,传统交易策略已难以应对。LLM通过多模态能力,能够实时处理海量异构数据,包括政策公告、设备检修信息、天气报告等非结构化数据,构建更精准的电力市场预测模型。智能交易系统主要包含三大核心模块:市场情报感知与理解器、融合LLM的短期电价预测模型和自适应交易策略生成器。这些模块协同工作,可在几分钟内完成事件分析、价格预测和策略生成,显著提升交易效率。系统还能实现跨市场套利和动态风险管理,但需注意数据质量、模型验

专注AI大模型,软件混淆,授权 1263

C#委托之如何理解委托面试常见题:

委托(delegate)是一种存储函数引用的类型。这听起来相当深奥,但其机制是非常简单的。委托的声明非常类似于函数,但不带函数体,且要使用delegate 关键字。委托的声明制定了一个返回类型和一个参数列表。 定义了委托后,就可以声明该委托类型的变量。接着把这个变量初始化为与委托具有相同返回类型和参数列表的函数引用。之后,就可以使用委托变量调用这个函数,就像该变量是一个函数一样。 有了引用函数的变...

qq_41231360的博客 3204

【Dify】知识库智能检索应用

本文介绍了一个基于大语言模型的知识库检索系统,实现从自然语言提问到智能回答的自动化流程。该系统通过知识检索节点定位相关信息,利用重排序模型优化结果,最后由大语言模型生成自然语言答案。核心模型包括InternLM2-7B和BCE重排序模型。工作流程包含输入问题、检索重排序、智能生成和答案输出四个阶段,适用于企业知识管理、客户支持、教育培训等多种场景,能显著提升信息检索效率和准确性。文章还提供了相关开发文档链接,涵盖AIGC工具平台搭建、常见问题解决等内容。

Mr数据杨 1002

C# 委托

委托,在百度百科中的释义是“指把事情托付给别人或别的机构(办理)”,也就是说,一件事,自己不亲自做,而是将这件事交给第三方去做。比如说老板A要发表演讲,需要写一个演讲稿,A可以选择自己写,也可以选择让员工B去写,那么A让B写演讲稿这个行为就是委托。在维基百科中,有这么一句话,是专门对c#中委托(delegate)的释义。.Net Framework上的程序设计语言如C#、Visual Basic的一类数据类型用于存储多个函数指针,称为委托(delegate)。

sc_1313的博客 2359

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

C#中委托

文章目录一、C#委托二、隐式类型与匿名类型三、C#扩展方法与yield关键字四、Lambda表达式 一、C#委托 举例1: 创建控制台应用程序 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace TheOne { //声明委托 public delegate string Translatio

weixin_46596213的博客 4438

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

C#——委托

Action是.NET Framework内置的泛型委托,可以使用Action委托以参数形式传递方法,而不用显示声明自定义的委托。使用多播委托就可以按照顺序调用多个方法,多播委托只能得到调用的最后一个方法的结果,一般我们把多播委托的返回类型声明为void。引用可在运行时被改变。定义了一个委托叫做 IntMethodInvoker ,这个委托可以指向带有一个int类型的参数,并且返回值是void的一个方法。在定义好委托后就可以实例化委托,命名方法委托在实例化委托时必须带入方法的具体名称或者是null。

m0_51743362的博客 1万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Kotlin 类委托与属性委托

介绍委托模式、Kotlin的委托机制:类委托以及属性委托

weixin_42643321的博客 1325

C#中为啥要有委托,以及委托的使用。

通俗讲,所谓委托就是将函数作为变量去使用。 一个类似的动作一直在做。但是还有细微的差别,比如:中国人问好是:"你好,XXX",而美国人问好是:“Hello,XXX” 将问好这个动作封装为函数的话,就会出现如下两个函数,这两个函数应该这么写: public static void ChineseSayHi(string name){ Console.WriteLine("你好"...

qq_41877039的博客 3171

C# 委托和事件委托

C# 本文描述了什么是委托,什么是事件委托,如何他们,并使用C#代码描述了如何实现的。 目录: 什么是委托? 1、概念 2、代码描述委托 什么是事件委托? 1、概念 2、代码描述事件委托

C/C#、Android driver、STM32、Linux等等。 1987

委托使用详解

委托太常见了,能灵活运用可以使你在编程中游刃有余。简单说它就是一个能把方法当参数传递的对象,而且还知道怎么调用这个方法,同事也是力度更小的“接口” 委托的简单使用 一个委托类型定义了该类型的实例能调用一类方法,这些方法含有同样的返回类型和同样参数(类型和个数相同)。委托和接口一样,可以定义在类的外部。如下定义了一个委托类型-Calculator: delegateintCalcul...

小目标一个亿 4883

c#的委托

最近一直遇到c#的委托,刚开始看的云里雾里的,后来以c++的函数指针来类比就醍醐灌顶了。所以特此记载下来。 因为最先接触的是c++,所以先来看c++的函数指针,再来讲c#的委托。 一、c++的函数指针 参考c++primer Plus 第6版 函数有地址,函数的地址是存储其机器语言代码的内存的开始地址。 函数地址:函数名。比如说Test()是一个函数,那么Test就是这个函数的地址。要将...

Arcobaleno 5672

C# 委托和事件(委托)

回调(callback)函数是Windows编程的一个重要部分。C或C++编程背景,在许多Windows API中使用过回调。VB添加AddressOf关键字后,开发人员就可以利用以前一度受到限制的API。回调函数实际上是方法调用的指针也称为函数指针。.NET以委托的形式实现函数指针的概念。C中函数指针只不过是一个指向存储单元的指针,无法说出这个指针实际指向什么,像参数和返回类型等更不知晓。

钢铁男儿 734

类委托与属性委托

类委托 类委托就是 现在有一个类需要实现某接口,发现有一个对于这个接口已经实现好的类,可以直接将这个现成的类拿来使用,也就是说本类继承某接口的任务委托了一个现成已经实现好的类的实例。 interface BASE{ fun say(); } interface BASE2{ fun say2(); } class SUB: BASE, BASE2{ override fu...

Ruger的博客 1194

Kotlin委托

Kotlin这语言有一个特点,它直接支持一些特别有用的设计模式在里面,如Kotlin的对象声明(单例),我们今天讲它的另外一种:委托。 在委托设计模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。许多其他设计模式,如状态模式、策略模式、访问者模式实际上也采用了委托模式。委托模式使得我们可以用聚合来替代继承,它还使我们可以模拟mixin。举个例子: 模拟打印机Printer拥有针式打印机RealPrinter的实例,Printer拥有的方法print()将处理转交给RealPr

weixin_40763897的博客 1970

Kotlin 委托

Kotlin委托是一种强大的语言特性,通过by关键字支持委托模式。分为类委托和属性委托两种形式:类委托将接口实现交给其他对象,减少样板代码;属性委托将属性的访问修改逻辑委托给其他对象,支持懒加载、可观察等特性。内置委托包括直接委托、懒加载、可观察属性和映射属性等,能够简化代码并提高可维护性。委托模式强调任务的专业分工,与代理模式的身份代表有所不同。通过委托,Kotlin实现了更灵活、简洁的代码组织方式。

xiangxiongfly 1897

什么是委托,委托的本质是什么?

跟方法有点类似,有参数,返回值,访问修饰符+delegate --委托--特殊的方法?委托的本质是什么?是方法吗?反编译试试:发现定义的委托-----再CustomDelegate ----有对应的class委托的本质是什么?---Class(类),继承自一个MulticastDelegate的特殊类,自己在定义类的时候,是无法继承的。包含的有构造函数和方法。委托既然是一个类---怎么使用这个类?new ---调用方法/属性");x = 100;");x = 100;

我是菜鸟 893
上一篇: .NET Framework中的事件
下一篇: HttpHandler
mx5721
博客等级 码龄17年 24粉丝 104原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值