详解C#委托,事件与回调函数(推荐)

c#笔记5 详解事件的内置类型EventHandler、windows事件在winform中的运用 从响应用户操作来看事件,解释Windows事件。详细解析事件的用法语法和在图形化界面中触发的本质。 阅读详情

来自:http://www.cnblogs.com/birdshover/archive/2008/01/07/1029471.html#2438089 

.Net编程中最经常用的元素,事件必然是其中之一。无论在ASP.NET还是WINFrom开发中,窗体加载(Load),绘制(Paint),初始化(Init)等等。
“protected void Page_Load(object sender, EventArgs e)”这段代码相信没有人不熟悉的。细心一点一定会发现,非常多的事件方法都是带了“object sender, EventArgs e”这两个参数。这是不是和委托非常相似呢?

一、委托(有些书中也称为委派)

委托是什么呢?这个名字的意思已经赋予了我们想象的空间,你是编程的,你现在正在写一个ASP.NET网页,而JS是你不熟悉的,于是你委托你的一位同事来帮助你完成JS部分。这就是委托,把你所不能做的事情交给其他人去做。而怎么知道是哪个人去做呢?当然是要知道名字!而为了区别名字一样的不同人,因此,需要描述一个特征。

在C#中,委托的作用是这样描述的:委托就像一个函数的指针,在程序运行时可以使用它们来调用不同的函数。这个其实和你委托同事完成 JS代码一样。如果有两位同事可以做这件事情,他们只要做的结果能够满足你的需求(就像一个接口),尽管他们做的过程不一样,并且作出的效果也不一样,但是,能够达到你的要求就可以了。

1、简单的委托

那委托需要承载哪些信息呢?首先,它存储了方法名,还有参数列表(方法签名),以及返回的类型。比如:
delegate string/*返回类型*/ ProcessDelegate(int i);
这就是一个委托的定义。蓝色部分是声明委托的关键字,红色部分是返回的类型,而黑色部分是委托的类型名,和一个类名差不多,而()里的就是参数部分。它的意思是,你要使用这个委托来做事情的话,那么,做事情的方法必须满足以下条件:
1、返回类型和委托的返回类型一致,这里是string类型;
2、能且只能有一个参数,并且是int类型。
OK,满足以上两个条件,一切就可以工作了:)

例如:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 
 5 namespace TestApp
 6 {
 7     /// <summary>
 8     /// 委托
 9     /// </summary>
10     /// <param name="s1"></param>
11     /// <param name="s2"></param>
12     /// <returns></returns>
13     public delegate string ProcessDelegate(string s1, string s2);
14 
15     class Program
16     {
17         static void Main(string[] args)
18         {
19             /*  调用方法  */
20             ProcessDelegate pd = new ProcessDelegate(new Test().Process);
21             Console.WriteLine(pd("Text1", "Text2"));
22         }
23     }
24 
25     public class Test
26     {
27         /// <summary>
28         /// 方法
29         /// </summary>
30         /// <param name="s1"></param>
31         /// <param name="s2"></param>
32         /// <returns></returns>
33         public string Process(string s1,string s2)
34         {
35             return s1 + s2;
36         }
37     }
38 }
输出的结果是:
Text1Tex2


2、泛型委托

泛型的委托,就是然参数的类型不确定,例如代码改写为:
using System;
using System.Collections.Generic;
using System.Text;

namespace TestApp
{
    
/// <summary>
    
/// 委托
    
/// </summary>
    
/// <param name="s1"></param>
    
/// <param name="s2"></param>
    
/// <returns></returns>
    public delegate string ProcessDelegate<T,S>(T s1, S s2);

    
class Program
    {
        
static void Main(string[] args)
        {
            
/*  调用方法  */
            ProcessDelegate
<string,int> pd = new ProcessDelegate<string,int>(new Test().Process);
            Console.WriteLine(pd(
"Text1", 100));
        }
    }

    
public class Test
    {
        
/// <summary>
        
/// 方法
        
/// </summary>
        
/// <param name="s1"></param>
        
/// <param name="s2"></param>
        
/// <returns></returns>
        public string Process(string s1,int s2)
        {
            
return s1 + s2;
        }
    }
}

输出的结果就是:
Text1100

泛型的详细内容不属于本文的介绍范围,这里不加多说了。

二、事件

在某件事情发生时,一个对象可以通过事件通知另一个对象。比如,前台完成了前台界面,他通知你,可以把前台和你开发的程序整合了。这就是一个事件。可以看出事件是在一个时间节点去触发另外一件事情,而另外一件事情怎么去做,他不会关心。就事件来说,关键点就是什么时候,让谁去做。

在C#中,时间定义关键字是event。例如:
event ProcessDelegate ProcessEvent;

整个事件定义方法以及执行过程:
using System;
using System.Collections.Generic;
using System.Text;

namespace TestApp
{
    
/// <summary>
    
/// 委托
    
/// </summary>
    
/// <param name="s1"></param>
    
/// <param name="s2"></param>
    
/// <returns></returns>
    public delegate void ProcessDelegate(object sender, EventArgs e);

    
class Program
    {
        

        
static void Main(string[] args)
        {
            
/*  第一步执行  */
            Test t 
= new Test();
            
/* 关联事件方法,相当于寻找到了委托人 */
            t.ProcessEvent 
+= new ProcessDelegate(t_ProcessEvent);
            
/* 进入Process方法 */
            Console.WriteLine(t.Process()); 

            Console.Read();
        }

        
static void t_ProcessEvent(object sender, EventArgs e)
        {
            Test t 
= (Test)sender;
            t.Text1 
= "Hello";
            t.Text2 
= "World";
        }
    }

    
public class Test
    {
        
private string s1;

        
public string Text1
        {
            
get { return s1; }
            
set { s1 = value; }
        }

        
private string s2;

        
public string Text2
        {
            
get { return s2; }
            
set { s2 = value; }
        }


        
public event ProcessDelegate ProcessEvent;

        
void ProcessAction(object sender, EventArgs e)
        {
            
if (ProcessEvent == null)
                ProcessEvent 
+= new ProcessDelegate(t_ProcessEvent);
            ProcessEvent(sender, e);
        }

        
//如果没有自己指定关联方法,将会调用该方法抛出错误
        void t_ProcessEvent(object sender, EventArgs e)
        {
            
throw new Exception("The method or operation is not implemented.");
        }

        
void OnProcess()
        {
            ProcessAction(
this, EventArgs.Empty);
        }

        
public string Process()
        {
            OnProcess();
            
return s1 + s2;
        }
    }
}
 
感觉到了什么?是不是和代码注入了差不多,相当于是可以用任意符合委托接口(委托确实很像接口)的代码,注入到Process过程。在他返回之前给他赋值。

三、回调函数

打了这么多字,好累啊!

回调函数就是把一个方法的传给另外一个方法去执行。在C#有很多回调函数,比如异步操作的时候。这里先举个例子:
using System;
using System.Collections.Generic;
using System.Text;

namespace TestApp
{
    
/// <summary>
    
/// 委托
    
/// </summary>
    
/// <param name="s1"></param>
    
/// <param name="s2"></param>
    
/// <returns></returns>
    public delegate string ProcessDelegate(string s1, string s2);

    
class Program
    {
        
static void Main(string[] args)
        {
            
/*  调用方法  */
            Test t 
= new Test();
            
string r1 = t.Process("Text1", "Text2", new ProcessDelegate(t.Process1));
            
string r2 = t.Process("Text1", "Text2", new ProcessDelegate(t.Process2));
            
string r3 = t.Process("Text1", "Text2", new ProcessDelegate(t.Process3));

            Console.WriteLine(r1);
            Console.WriteLine(r2);
            Console.WriteLine(r3);
        }
    }

    
public class Test
    {
        
public string Process(string s1,string s2,ProcessDelegate process)
        {
            
return process(s1, s2);
        }

        
public string Process1(string s1, string s2)
        {
            
return s1 + s2;
        }

        
public string Process2(string s1, string s2)
        {
            
return s1 + Environment.NewLine + s2;
        }

        
public string Process3(string s1, string s2)
        {
            
return s2 + s1;
        }
    }
}

输出结果:
Text1Text2
Text1
Text2
Text2Text1

Process方法调用了一个回调函数,当然这里只执行了回调函数。可以看出,可以把任意一个符合这个委托的方法传递进去,意思就是说这部分代码是可变的。而设计上有一个抽离出可变部分代码的原则,这种用法无疑可以用到那种场合了。

全文完。http://birdshover.cnblogs.com   Birdshover

Ps:累死我了,休息休息~~~~

C#窗体间常用的几种传值方式、以及委托与事件的详细介绍 窗体间的传值,最好使用委托方式传值,开始之前,我们先来说一下委托与事件的关系。 委托:是一个类。 事件:是委托类型的一个特殊实例,只能在类的内部触发执行。 首先创建2个窗体,这里我们以form1为发送窗体,form2为接收窗体 form1窗体 form2窗体 方式一(最简单的方式) form1窗体代码 using System; using Sys... 阅读详情

相关推荐

C#委托与事件完全指南(八):从基础到高级应用实践

通过灵活运用委托与事件,开发者可以构建出高内聚、低耦合的系统架构,实现真正的松耦合设计。记住:优秀的架构=恰当的事件驱动设计+合理的委托抽象!

xienda的博客 1227

详解C#委托,事件与回调函数

.Net编程中最经常用的元素,事件必然是其中之一。无论在ASP.NET还是WINFrom开发中,窗体加载(Load),绘制(Paint),初始化(Init)等等。“protected void Page_Load(object sender, EventArgs e)”这段代码相信没有人不熟悉的。细心一点一定会发现,非常多的事件方法都是带了“object sender, EventArgs e”这...

weixin_33774615的博客 957

C#委托深度剖析:从多播机制到Lambda闭包的核心原理与高效实践

委托是C#实现回调、事件驱动编程的核心工具,结合Lambda和匿名方法可极大简化代码。理解其底层机制(如多播、协变/逆变)和性能特征,能帮助开发者避免常见陷阱,编写高效、灵活的代码。

Rocn666的博客 1616

回调函数与C#委托机制

回调函数 回调函数是一种有用的编程机制,就是通过函数指针调用的函数。C#里通过委托来提供回调函数的机制。不同于C/C++,委托确保回调方法是类型安全的,支持静态方法和类实例的成员方法,还允许顺序调用多个方法。 委托的内部构造 编译器实际上会为委托定义一个完整的类。类包含: 4个方法:一个构造器、Invoke函数、BeginInvoke和EndInvoke。 三个主要的字段 _target、 _methodPtr、 _invocationList 字段 类型 说明 _target Sys

gaming & coding 995

【从零开始入门unity游戏开发之——C#篇33】C#委托(`Delegate`)和事件(`event` )、事件与委托的区别、Invoke()的解释

C#委托(`Delegate`)和事件(`event` )、事件与委托的区别、Invoke()的解释

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 2021

C#中的委托、事件与委托链

本文深入探讨了C#中的委托(Delegate)和事件(Event)的概念及其应用,通过创建和使用委托来实现方法的动态绑定,进而讨论了如何在委托中使用链式调用,以及事件如何依赖委托来通知其他类特定情况的发生。文章还介绍了.NET平台提供的Action和Func委托类型,以及如何在C#中定义和触发自定义事件。

weixin_29781865的博客 431

Page_Load(object sender, EventArgs e)的执行顺序

问题:1.创建一个用户控件,包含一个下拉框。用于选择月份。在该用户控件的Page_Load响应函数中写以下代码:    protected void Page_Load(object sender, EventArgs e)    ...{        if (!IsPostBack)        ...{            for (int i = 1; i  12; i++

xiaomin98的专栏 1万+

详解C#委托,事件与回调函数

详解C#委托,事件与回调函数

c#:委托与回调函数示例

c#:委托与回调函数示例 上一篇文章已经给大家详细讲解过委托的意思,如何声明定义,如何通过委托调用函数,以及委托中的多播等……今天是刚刚学到委托新的用法——可以将方法当作参数来传递,并且不需用示例委托。所以今天来给大家再次拿出来详细讲解一下 一、委托 委托理解的追加 ​ (1)委托是c#实现回调函数的一种机制 ​ (2)使用委托就能讲方法当作变量来进行传递——这个是比较重要的 ​ (3)委托是引用类型,说白了委托是一种数据类型,什么数据类型——用户自定义类型,这种类型赋值赋值需要赋一个与之对应的方法,也就

abraham_ly的博客 4159

pwm电机调速的原理介绍与代码实现

1、pwm实现调速的原理与介绍 PWM(Pulse Width Modulation)脉冲宽度调制。 1)占空比 pwm占空比就是一个脉冲周期内有效电平在整个周期所占的比例。 通过调节PWM的占空比就能调节IO口上电压的持续性变化,因此也能够控制外设的功率进行持续性变化,也就能控制直流电机的转速快慢。 那么重点就在于如何调节PWM波形的输出。如下图所示 图中的ARR是我们给定时器的一个预装载值,CCRx的上下变化是产生PWM波的关键。我们假设ARR大于CCRx的部分输出为高电平(即t1-t2、t3-t4

Clichong 7万+

最新打赏系统打赏源码麒麟最新打赏源码喜盈门打赏知识付费课程教程直播讲解

打赏源码打赏系统

qq_41095398的博客 2037

C# 委托与事件总结

C# 中的委托和事件可以说是超级拦路虎了,一个不小心就容易让人直接放弃学习。最近几天花了点时间钻研了一下,查看了一些资料,希望做个总结。 我还达不到技术大佬的级别,主要就是做个**自我总结**,很推荐大家看一下我下面发的参考资料里的文章和视频,那些是真正的大佬产出的内容。

萌宅鹿的技术小屋 2617

AI大模型与碳足迹评估结合模式及示范案例

AI大模型与碳足迹评估相结合,可以提供更精确、更快速的碳排放量计算,优化减排策略,并促进可持续发展目标的实现。

贾贾的博客 3944

C# 委托和事件

委托是一种特殊的类型,用于安全地封装一个或多个方法,并将这些方法作为参数进行传递或调用。委托是方法的引用,可以看作是指向方法的指针。事件是委托的进一步封装,用于在类或对象之间传递消息。事件是类的一部分,通过event关键字声明。

語衣的个人博客 3420

循环神经网络(RNN)

在之前学习了全连接神经网络(DNN)模型,网络结构都是从输入层到隐含层再到输出层,层与层之间是全连接或部分连接的,但每层之间的节点是无连接的。 一、神经网络基础 神经网络可以当做是能够拟合任意函数的黑盒子,只要训练数据足够,给定特定的x,就能得到希望的y,结构图如下: 将神经网络模型训练好之后,在输入层给定一个x,通过网络之后就能够在输出层得到特定的y,那么既然有了这么强大的模型,为什么还需要RNN(循环神经网络)呢? 二、为什么需要RNN(循环神经网络) 考虑这样一个问题,如果要预测句子的下一个单词是什么

小朱小朱绝不认输的博客 2万+

xenomai内核解析--嵌入式实时linux概述

Linux系统作为一个GPOS(通用操作系统)发展至今已经非常成熟可靠了,并且由于遵循GPL协议,开放所有系统源代码,非常易于裁剪。更重要的是,与其他开源的GPOS或RTOS相比,Linux系统支持多种处理器、开发板,提供多种软件开发工具,同时Linux系统对网络和图形界面的支持非常出色。显然,选择Linux操作系统在产品的开发周期和成本控制方面都有巨大优势。 虽然Linux系统功能强大、实用性强...

wsg1100 3701

C# 一文读懂委托与事件

诞生:技术点出来的原因就是 有一些需要将方法作为入参 处理的情况 比如 业务处理完需要回调函数 那就需要传函数入参委托是C#中的一种类型安全函数指针,允许将方法作为参数传递或存储。它本质上是面向对象的,对方法签名抽象封装(参数列表和返回类型),并支持多播(绑定多个方法)。事件是基于委托的发布-订阅模式,用于对象间通信。它封装了委托的调用权限,确保外部代码只能通过+=和-=订阅或取消订阅。就是特殊的委托加了权限的委托只允许在声明的类内部 进行invoke 哪怕子类也不行 外部调用也不行。

Marzlam的博客 1506

HAMi 核心模块与架构设计

HAMi 的架构设计是围绕 Kubernetes 生态系统构建的,通过扩展 Kubernetes 的调度能力和设备管理能力,为用户提供了高效、灵活的异构设备虚拟化和管理解决方案。

北斗云的博客 2552

C#基础之委托,事件

C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate)都派生自类。C# 事件(Event)是一种成员,用于将特定的事件通知发送给订阅者。事件通常用于实现观察者模式,它允许一个对象将状态的变化通知其他对象,而不需要知道这些对象的细节。事件(Event。

上善若泪 2732

南京银行信息技术岗提前批笔试与面试

1、笔试 笔试大致可以分为三部分:性格测试、行测题目、专业知识 性格测试 性格测试一般会有较多的体量,可能一共大概有一百多道接近两百道的样子,这个是不限时的。 前面有100道是这样的题目,就是有四个选项都是各种形容词,然后分别选出最符合自己的与最不符合自己的选项。这种题你就顺着自己的潜意识填就行了,但是前后要一致,我怀疑他出这么多题,可能就是考一考你记不记得前面填了啥。比如你做到第90题的时候,可能会出现和前面第2题类似的四个形容词,更有甚者就是一模一样的,你要对自己之前选的什么有个比较清楚的记忆。

qq_40971025的博客 6922

基于STM32F103C8T6单片机设计CAN接口8路继电器控制板硬件(原理图+PCB)+软件源码

基于STM32F103C8T6单片机设计CAN接口8路继电器控制板硬件(原理图+PCB)+软件源码,仅供学习及设计参考。

GJZGRB的博客 1417

C# 异步事件调用委托

如何实现异步事件调用呢?事件其实是一种MulticastDelegate(多播委托)。而MulticastDelegate类提供了一个GetInvocationList方法,该方法返回此多播委托的委托调用数组。利用该方法就能实现我们的异步事件调用功能。 using System; using System.Threading; using System.Runtime.Remoting...

Peter的博客 5829

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

C# 事件与委托

委托是一种类型安全的函数指针,它允许将方法作为参数传递给其他方法。

让每一个想学习编程的人,都能学会,都能看懂,看了都有收获! 1362

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

C#委托和事件

平时用户自定义委托的机会不太多,一般都使用C#自带的委托:2.如何定义委托?使用delegate关键字定义观察一下:委托和方法的形式的区别:a. 没有方法体 b. 方法返回值前多一个delegate关键字。可以没有返回,可以没有参数。在类内部,在类外部, 但不能在方法内部定义一个事件。使用event关键字。EventHandler委托类型 MyClick就是委托实例,即事件变量。// 默认值null类内部,不能在方法内部。

weixin_61819056的博客 1039

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

C#委托和事件 学习与练习

首先什么是委托和事件 委托从字面上理解就是一种代理,类似于房屋中介,由租房人委托中介为其租赁房屋。 在 C# 语言中,委托则委托某个方法来实现具体的功能。 委托是一种引用类型,虽然在定义委托时与方法有些相似,但不能将其称为方法。 委托在使用时遵循三步走的原则,即定义声明委托、实例化委托以及调用委托。 从数据结构来讲,委托是和类一样是一种用户自定义类型。 委托是方法的抽象,它存储的就是一系列具有...

风风风儿带我飞的博客 980

C#代码解耦利器:委托与事件(Delegate & Event)从入门到实践 (Day 23)

在前一天的学习中,我们探讨了如何通过异常处理和调试来增强代码的健壮性。今天,我们将深入 C# 的一个核心特性——委托(Delegate)和事件(Event)。它们是实现事件驱动编程和代码解耦的强大武器,对于构建灵活、可维护的系统(尤其是在像 Unity 这样复杂的开发环境中)至关重要。理解委托和事件,能让你在不同模块间建立松耦合的通信机制,告别“牵一发而动全身”的窘境。从本质上讲,委托(Delegate)是一种引用类型,它可以“持有”

吴师兄大模型的博客 1387
上一篇: HashSet 、 Dictionary 、List性能对比
下一篇: Installshield2010实现web部署和数据库安装示例
ArvinStudy
博客等级 码龄15年 83粉丝 193原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值