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

2023-10-31

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


上一篇文章已经给大家详细讲解过委托的意思,如何声明定义,如何通过委托调用函数,以及委托中的多播等……今天是刚刚学到委托新的用法——可以将方法当作参数来传递,并且不需用示例委托。所以今天来给大家再次拿出来详细讲解一下

一、委托

委托理解的追加

​ (1)委托是c#实现回调函数的一种机制

​ (2)使用委托就能讲方法当作变量来进行传递——这个是比较重要的

​ (3)委托是引用类型,说白了委托是一种数据类型,什么数据类型——用户自定义类型,这种类型赋值赋值需要赋一个与之对应的方法,也就是返回值类型以及参数列表相同的方法

2、回调函数

专业术语:

​ 回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。

​ **注意:回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。**通俗点讲就是讲某个实现函数作为参数传入另一个函数中去,当然我们可以通过委托接口等其他一些手段实现这种方式。

自己的理解:

​ 其实说白了回调函数就是指把一个方法当作一种参数传给另一个方法去执行,目的肯定就不用说了,就是来完成某种任务或者功能。

3、委托与回调函数的示例

注意:这里讲的是同步委托的调用

同步委托掉用?

​ 同步委托调用:就是说你去银行存钱,把钱给柜员,他们会帮你点钞、存款,然后给您存折或卡。那么您就相当于把钱委托给了柜员,让他去执行存钱的这个函数。

(1)静态委托

	public delegate void Age(string a,int b);//定义了一个委托
    class Found
    {
        //定义一个回调函数,使之能以参数的形式进行传递
        public static void Much(string a,int b)
        {
            Console.WriteLine("我是"+a+"今年"+b+"岁了");
        }
        /// <summary>
        /// 有参方法
        /// </summary>
        /// <param name="age">委托类型</param>
        public static void Many(Age age)//这里就是另一方实现回调函数的地方
        {
            if (age!=null)//判断是否传来了一个不为空的参数
            {
                Console.WriteLine("有Age类型的委托");
            }
            age("小明",20);//这里就实现并调用了回调函数
        }
    }
    class Program
    {
       
        static void Main(string[] args)
        {
            Found.Many(Found.Much);//这里就是Age委托Many方法来实现回调函数Much
        }
    }

(2)实例委托

	delegate void DelegateAdd1();//定义一个无参的委托,类型为DekegeteAdd1类型,
    delegate void DelegateAdd2(string value);//定义一个有参的委托,类型为DekegeteAdd2类型
    class DelegateApp
    {
//——————————————————————————————————这里涉及到了方法的重载—————————————————————————————————————————————
        /// <summary>
        /// 有参方法1——回调函数
        /// </summary>
        /// <param name="value">传递的字符串数据</param>
        public void Fild1(string value)
        {
            Console.WriteLine("有参方法1——————{0}", value);
        }
        /// <summary>
        /// 无参方法1——回调函数
        /// </summary>
        public void Fild1()
        {
            Console.WriteLine("无参方法1");
        }
        /// <summary>
        /// 有参方法2——回调函数
        /// </summary>
        /// <param name="value">传递的字符串数据</param>
        public void Fild2(string value)
        {
            Console.WriteLine("有参方法2——————{0}", value);
        }
        /// <summary>
        /// 无参方法2——回调函数
        /// </summary>
        public void Fild2()
        {
            Console.WriteLine("无参方法2");
        }
        /// <summary>
        /// 有参方法3——回调函数
        /// </summary>
        /// <param name="value">传递的字符串数据</param>
        public void Fild3(string value)
        {
            Console.WriteLine("有参方法2——————{0}", value);
        }
        /// <summary>
        /// 无参方法3——回调函数
        /// </summary>
        public void Fild3()
        {
            Console.WriteLine("无参方法3");
        }
//———————————————————————————————————————以上的方法均为定义回调函数—————————————————————————————————————
//—————————————————————————————————下面的方法是委托的任务,即实现回调函数————————————————————————————————
        /// <summary>
        /// 执行委托的任务——实现回调函数
        /// </summary>
        /// <param name="add1">DelegateAdd1委托类型的参数</param>
        /// <param name="add">DelegateAdd2委托类型的参数</param>
        /// <param name="value">string类型的字符串</param>
        public void Print(DelegateAdd1 add2,DelegateAdd2 add,string value)
        {
            add2();//因为add2形参对应的传过来的实参的add1,因为add2的类型就是DelegateAdd(委托类型)是无参的,又因为add1中值就是一个方法,所以就可以以方法的形式来调用输出
            //这里的add2形参对应的是一个无参的方法,因为DelegateAdd1类型(委托类型)是无参的
            //而add形参对应的是一个有参的方法,因为DelegateAdd2类型(委托类型)是有参的
            add(value);//而这块add形参对应的值是add_01就是有参的嘛,所以就必须给它一个参数
        }
//外部类的调用
   class Program
    {
        static void Main(string[] args)
        {
            //第二种的
            DelegateApp d = new DelegateApp();//实例化对象DelegateApp来调用类中的方法
            DelegateAdd1 add1, add2, add3;//声明三个DeleagteAdd1类型(委托类型)的变量,因为这个类型是无参的,所以只能存储无参的方法
            add1 = d.Fild1;//给DelegateAdd1类型的变量add1赋值一个(无参的)方法
            add2 = d.Fild2;
            add3 = d.Fild3;
            DelegateAdd2 add_01, add_02, add_03;//声明三个Delegate类型(委托类型)的变量,,因为这个类型是有参的,所以只能存储有参的方法
            add_01 = d.Fild1;//给DelegateAdd2类型的变量add_01赋值一个(有参的)方法
            add_02 = d.Fild2;
            add_03 = d.Fild3;
           	d.Print(add1, add_01,"已执行");//委托Print方法来实现回调函数Fild1(有参和无参)重载
        }
    }

(3)使用数组和泛型来实现委托

delegate void DelegateAdd1();
    delegate void DelegateAdd2(string value);
    class DelegateApp
    {
        /// <summary>
        /// 有参方法1
        /// </summary>
        /// <param name="value">传递的字符串数据</param>
        public void Fild1(string value)
        {
            Console.WriteLine("有参方法1——————{0}", value);
        }
        /// <summary>
        /// 无参方法1
        /// </summary>
        public void Fild1()
        {
            Console.WriteLine("无参方法1");
        }
        /// <summary>
        /// 有参方法2
        /// </summary>
        /// <param name="value">传递的字符串数据</param>
        public void Fild2(string value)
        {
            Console.WriteLine("有参方法2——————{0}", value);
        }
        /// <summary>
        /// 无参方法2
        /// </summary>
        public void Fild2()
        {
            Console.WriteLine("无参方法2");
        }
        /// <summary>
        /// 有参方法3
        /// </summary>
        /// <param name="value">传递的字符串数据</param>
        public void Fild3(string value)
        {
            Console.WriteLine("有参方法2——————{0}", value);
        }
        /// <summary>
        /// 无参方法3
        /// </summary>
        public void Fild3()
        {
            Console.WriteLine("无参方法3");
        }
  //实现回调函数的方法
        public void Print(DelegateAdd1[] arry,List<DelegateAdd2> list,string value)
        //使用数组和泛型来将所有的回调函数全部实现,其中数组中存储的无参回调函数,泛型中存储的是有参回调函数
        {
            for (int i = 0; i < arry.Length; i++)//将存储在数组中的变量全部拿出来,并以方法的形式调用
            {
                arry[i]();//因为通过索引取的时候,arry[0]就代表一个DelegateAdd类型(委托类型)的变量,它这个变量是无参的方法,所以就可以以方法的形式来调用
            }
            for (int i = 0; i < list.Count; i++)//将存储在泛型中的变量全部拿出来,并以方法的形式调用
            {
                list[i](value);//vale就是外界传过来的string类型的实际参数
            }
        }
    }
//————————————————————————————————————————————外部类调用——————————————————————————————————————————————
  class Program
    {
       
        static void Main(string[] args)
        {
            DelegateApp d = new DelegateApp();//实例化对象DelegateApp来调用类中的方法
            DelegateAdd1 add1, add2, add3;//声明三个DeleagteAdd1类型(委托类型)的变量,因为这个类型是无参的,所以只能存储无参的方法
            add1 = d.Fild1;//给DelegateAdd1类型的变量add1赋值一个(无参的)方法
            add2 = d.Fild2;
            add3 = d.Fild3;
            DelegateAdd2 add_01, add_02, add_03;//声明三个Delegate类型(委托类型)的变量,,因为这个类型是有参的,所以只能存储有参的方法
            add_01 = d.Fild1;//给DelegateAdd2类型的变量add_01赋值一个(有参的)方法
            add_02 = d.Fild2;
            add_03 = d.Fild3;
            DelegateAdd1[] arry = {add1,add2,add3 };//创建一个数组来存储DelegateAdd1类型的变量
            List<DelegateAdd2> list= new List<DelegateAdd2>();//实例化一个泛型来存储DelegateAdd2类型的变量
            //将三个变量添加到泛型中
            list.Add(add_01);
            list.Add(add_02);
            list.Add(add_03);
            d.Print(arry, list, "已执行");//委托Print方法来实现所有的回调函数,第一个参数是数组,第二个是泛型,也就是说将全部的回调方法实现了
            Console.ReadKey();
        }
    }

以上三种方法结合后输出的结果:


以上均为自己在学习中总结的一些小知识点,希望能对您有一些帮助。如果本篇文章还有什么不完善的地方,或者对大家造成的误导,还请各位能够指出,来纠正为的错误,谢谢大家!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c#:委托与回调函数示例 的相关文章

  • 如何使用 pybrain 黑盒优化训练神经网络来处理监督数据集?

    我玩了一下 pybrain 了解如何生成具有自定义架构的神经网络 并使用反向传播算法将它们训练为监督数据集 然而 我对优化算法以及任务 学习代理和环境的概念感到困惑 例如 我将如何实现一个神经网络 例如 1 以使用 pybrain 遗传算法
  • 加快网络抓取速度

    我正在使用一个非常简单的网络抓取工具抓取 23770 个网页scrapy 我对 scrapy 甚至 python 都很陌生 但设法编写了一个可以完成这项工作的蜘蛛 然而 它确实很慢 爬行 23770 个页面大约需要 28 小时 我看过scr
  • 如何返回 json 结果并将 unicode 字符转义为 \u1234

    我正在实现一个返回 json 结果的方法 例如 public JsonResult MethodName Guid key var result ApiHelper GetData key Data is stored in db as v
  • Python3 在 DirectX 游戏中移动鼠标

    我正在尝试构建一个在 DirectX 游戏中执行一些操作的脚本 除了移动鼠标之外 我一切都正常 是否有任何可用的模块可以移动鼠标 适用于 Windows python 3 Thanks I used pynput https pypi or
  • 不同编程语言中的浮点数学

    我知道浮点数学充其量可能是丑陋的 但我想知道是否有人可以解释以下怪癖 在大多数编程语言中 我测试了 0 4 到 0 2 的加法会产生轻微的错误 而 0 4 0 1 0 1 则不会产生错误 两者计算不平等的原因是什么 在各自的编程语言中可以采
  • 如何使用原始 SQL 查询实现搜索功能

    我正在创建一个由 CS50 的网络系列指导的应用程序 这要求我仅使用原始 SQL 查询而不是 ORM 我正在尝试创建一个搜索功能 用户可以在其中查找存储在数据库中的书籍列表 我希望他们能够查询 书籍 表中的 ISBN 标题 作者列 目前 它
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • C# 中的递归自定义配置

    我正在尝试创建一个遵循以下递归结构的自定义配置部分
  • 如何在 Windows 命令行中使用参数运行 Python 脚本

    这是我的蟒蛇hello py script def hello a b print hello and that s your sum sum a b print sum import sys if name main hello sys
  • Pandas 将多行列数据帧转换为单行多列数据帧

    我的数据框如下 code df Car measurements Before After amb temp 30 268212 26 627491 engine temp 41 812730 39 254255 engine eff 15
  • clang 实例化后静态成员初始化

    这样的代码可以用 GCC 编译 但 clang 3 5 失败 include
  • 从库中捕获主线程 SynchronizationContext 或 Dispatcher

    我有一个 C 库 希望能够将工作发送 发布到 主 ui 线程 如果存在 该库可供以下人员使用 一个winforms应用程序 本机应用程序 带 UI 控制台应用程序 没有 UI 在库中 我想在初始化期间捕获一些东西 Synchronizati
  • 当操作繁忙时,表单不执行任何操作(冻结)

    我有一个使用 C 的 WinForms 应用程序 我尝试从文件中读取一些数据并将其插入数据表中 当此操作很忙时 我的表单冻结并且无法移动它 有谁知道我该如何解决这个问题 这可能是因为您在 UI 线程上执行了操作 将文件和数据库操作移至另一个
  • 使用for循环时如何获取前一个元素? [复制]

    这个问题在这里已经有答案了 可能的重复 Python 循环内的上一个和下一个值 https stackoverflow com questions 1011938 python previous and next values inside
  • Scipy Sparse:SciPy/NumPy 更新后出现奇异矩阵警告

    我的问题是由大型电阻器系统的节点分析产生的 我基本上是在设置一个大的稀疏矩阵A 我的解向量b 我正在尝试求解线性方程A x b 为了做到这一点 我正在使用scipy sparse linalg spsolve method 直到最近 一切都
  • 需要哪个版本的 Visual C++ 运行时库?

    microsoft 的最新 vcredist 2010 版 是否包含以前的版本 2008 SP1 和 2005 SP1 还是我需要安装全部 3 个版本 谢谢 你需要所有这些
  • 在 JavaScript 函数的 Django 模板中转义字符串参数

    我有一个 JavaScript 函数 它返回一组对象 return Func id name 例如 我在传递包含引号的字符串时遇到问题 Dr Seuss ABC BOOk 是无效语法 I tried name safe 但无济于事 有什么解
  • 如何在 C++ BOOST 中像图形一样加载 TIFF 图像

    我想要加载一个 tiff 图像 带有带有浮点值的像素的 GEOTIFF 例如 boost C 中的图形 我是 C 的新手 我的目标是使用从源 A 到目标 B 的双向 Dijkstra 来获得更高的性能 Boost GIL load tiif
  • Kivy - 单击按钮时编辑标签

    我希望 Button1 在单击时编辑标签 etykietka 但我不知道如何操作 你有什么想法吗 class Zastepstwa App def build self lista WebOps getList layout BoxLayo
  • 防止索引超出范围错误

    我想编写对某些条件的检查 而不必使用 try catch 并且我想避免出现 Index Out of Range 错误的可能性 if array Element 0 Object Length gt 0 array Element 1 Ob

随机推荐

  • 网络编程知识预备(5) ——libcurl库安装及其编程访问百度首页(断点续传)

    本文为学习笔记 整合课程内容以及下列文章 其中 libcurl函数库常用字段解读部分 参考博文 原文地址 作者 冬冬他哥哥 目录 Libcurl库简介 Libcurl等三方库的通用编译方法 三方库使用前通读方法 库的配置 编译 安装 调用l
  • protobuf生成prototxt文件

    使用protobuf可以分为以下几步 1 proto文件的定义 在这个文件中定义了最终生成的prototxt格式 举个例子如下所示 syntax proto2 package label proto message DetectLabel
  • scrapy缺点

    Scrapy 是一个功能强大的网络爬虫框架 但也有一些缺点 Scrapy 只能爬取静态网页 无法爬取动态网页 Scrapy 只能爬取一个网站的数据 无法爬取多个网站的数据 Scrapy 需要编写代码 对于那些不会编写代码的人来说可能会有些困
  • LiteOS内存管理

    1 内存管理简介 内存管理模块管理系统的内存资源 它是操作系统的核心模块之一 主要包括内存的初始化 分配以及释放 在系统运行过程中 内存管理模块通过对内存的申请 释放操作 来管理用户和OS对内存的使用 使内存的利用率和使用效率达到最优 同时
  • obs无法连接服务器?PotPlayer获取不到视频

    搭建基于nginx的rtmp直播服务器 https hywlovexyc info blog archives 572 rtmp server listen 1935 监听的端口 chunk size 4000 application yu
  • 删除中间节点

    题目 若链表中的某个节点 既不是链表头节点 也不是链表尾节点 则称其为该链表的 中间节点 假定已知链表的某一个中间节点 请实现一种算法 将该节点从链表中删除 例如 传入节点 c 位于单向链表 a gt b gt c gt d gt e gt
  • sqlserver查看数据表结构

    可以通过两种方式 1 sp help 表名 2 sp columns 表名
  • 我的世界服务器config文档,Essentials/配置文件/config.yml

    ops name color none nickname prefix max nick length 15 change displayname true change playerlist true add prefix suffix
  • Unity--虚拟轴

    1 查看虚拟轴 Edit gt project settings gt Input 2 获取虚拟轴 input GetAxis 用法 GetAxis Mouse X GetAxis Mouse Y GetAxis Mouse ScrollW
  • centos7Linux中的lvm、pv、vg、lv,以及Linux扩容,创建新分区

    概念 本着言简意赅的目的 以下概念会在扩容时用到 需熟知 不然会不理解具体操作在干什么 lvm 逻辑卷管理器 Logical Volume Manager 它使系统管理员可以更方便的为应用与用户分配存储空间 在LVM管理下的存储卷可以按需要
  • QT信号槽原理(一)connect函数

    目录 2个类型和1个签名 Qt ConnectionType QMetaMethod MethodType 方法签名 connect函数源码解析 函数原型 第一步 参数检查 第二步 获取信号和槽的index 第三步 检查信号和槽的参数是否匹
  • Opencv之图像固定阈值二值化处理threshold

    目录 一 图像二值化 二 threshold 三 代码 一 图像二值化 定义 图像的二值化 就是将图像上的像素点的灰度值设置为0或255 也就是将整个图像呈现出明显的只有黑和白的视觉效果 灰度值0 黑 灰度值255 白 一幅图像包括目标物体
  • Cygwin编译JNI的环境配置

    一 什么是NDK NDK提供了一系列的工具 帮助开发者快速开发C 或C 的动态库 并能自动将so和java应用一起打包成apk 这些工具对开发者的帮助是巨大的 NDK 集成了交叉编译器 并提供了相应的mk文件隔离CPU 平台 ABI 等差异
  • MacBook怎么安装使用Windows软件和虚拟机?

    作为一名MacBook用户 你可能会发现有些软件和应用程序只适用于Windows操作系统 但别担心 今天我们将介绍两种方法 让你的MacBook轻松安装Windows软件和运行Windows虚拟机 为你的工作 学习和娱乐任务带来更多可能性
  • Vue 3 使用 vue-echarts 的柱状图 barItem 和 x, y 轴点击事件实现

    需求背景 最近使用 Vue 3 开发柱状图功能 图表已经绘制完成了 但是突然有需求加进来要可以点击柱状图的柱子 barItem 和 x y 轴的坐标 然后根据点击的位置 处理不同区域的点击事件 作为 CV 程序员 第一时间搜索网上的解决方案
  • 抖音养号步骤有哪些?最重要的3步你做到了吗?

    国仁网络资讯 为大家整理一份超详细的 短视频运营手册 回复私信限时免费领取 有人问我 新手养号怎么养 老账号养号要怎么养 其实 严格来说 养号不分新老 不管你是刚注册的抖音号 还是已经用过很久的抖音号 养号都是运营账号必做的事项之一 那么
  • C++文件的读取详解,以及使用eof出现末行数据被读取两次情况

    目录 0 前言 对文件流的读写 文件打开方式 1 写文本文件 2 读文本文档 2 1使用efo函数判断出现数据被读取两次 3 二进制方式写文件 4 二进制读文件 5 按指定格式读写数据stringstream 0 前言 对文件流的读写 if
  • text/html & text/plain的区别

    需要了解的概念 Content Type 用于定义用户的浏览器或相关设备如何显示将要加载的数据 或者如何处理将要加载的数据 MIME MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型 当该扩展名文件被访问的时候 浏览器会自
  • Red Hat Enterprise Linux 7.9 下载

    1 Red Hat Linux 所有版本 5 6 7 8 9 下载 https pan baidu com s 1eSYuljc2Bt9OXZmWdZQ96A 提取码 cqfu 推荐 https pan baidu com s 1RISly
  • c#:委托与回调函数示例

    c 委托与回调函数示例 上一篇文章已经给大家详细讲解过委托的意思 如何声明定义 如何通过委托调用函数 以及委托中的多播等 今天是刚刚学到委托新的用法 可以将方法当作参数来传递 并且不需用示例委托 所以今天来给大家再次拿出来详细讲解一下 一