C#委托相关知识

news2024/11/23 12:40:20

最开始学习C#的时候,简单的看过委托,最近工作中经常需要使用到委托。这篇笔记是对之前看过的委托的一个补充,也是对最近工作中遇到的委托的一个总结吧。

这里使用的是窗体程序作为例子。实例在文末,可下载。

委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递。事件是一种特殊的委托。

有四种表现形态:delegate、Action、Func、predicate

委托定义要和作为其参数的方法形式一样,也就是说,参数、返回值及其他都是相同

先放一张最后实例的样图:

2323.png

(1):delegate委托。

delegate我们常用到的一种声明

Delegate至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型。

例:public delegate int MethodtDelegate(int x, int y);表示有两个参数,并返回int型。

委托实例化格式如下:

委托类名 委托实例名 = new 委托类名(Target) ;

MethodtDelegate fele = new MethodtDelegate(fun);

其中,委托实例名是自定义的名称,fun是要传入的方法的名称。注意fun是方法的引用,不能带()。带()的话是该方法的调用。区分引用和调用。

委托的实例化还有一种简单的方法:

委托类名 委托实例名 = Target;

MethodtDelegate dele = fun;

在需要委托实例的地方直接传入fun引用即可,C#编译器会自动根据委托类型进行验证,这称为“委托推断”。

实例:

// =========  delegate  ================
        /// <summary>
        /// 定义一个没有返回值的delegate委托(有参数)
        /// </summary>
        public delegate void MethodDelegate(Color color);
        /// <summary>
        /// 颜色下拉列表改变事件
        /// </summary>
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            Color color = Color.White;
            int index = comboBox1.SelectedIndex;
            switch (index)
            {
                case 0:
                    color = Color.Red;
                    break;
                case 1:
                    color = Color.Blue;
                    break;
                case 2:
                    color = Color.Black;
                    break;
                case 3:
                    color = Color.GreenYellow;
                    break;
            }
            // 实例化委托
            MethodDelegate delegates = new MethodDelegate(form2.SetColor);
 
            // 委托推断(简写的委托)Form2颜色变
            MethodDelegate delegateOnly = form2.SetColor;
 
            // 多播委托(一个委托,执行多个事件) FOrm2 和 Form3颜色都变
            delegateOnly += form3.SetColor;
            // 执行
            delegateOnly(color);
            // 清空委托
            ClearDelegate(delegateOnly);
        }

 Form2

public void SetColor(Color color)
{
     pictureBox1.BackColor = color;
     pictureBox1.Refresh();
}

Form3

public void SetColor(Color color)
{
     pictureBox1.BackColor = color;
     pictureBox1.Refresh();
}

(2):Action委托

Action是无返回值的泛型委托。

Action 表示无参,无返回值的委托

Action<int,string> 表示有传入参数int,string无返回值的委托

Action<int,string,bool> 表示有传入参数int,string,bool无返回值的委托

Action<int,int,int,int> 表示有传入4个int型参数,无返回值的委托

Action至少0个参数,至多16个参数,无返回值。

<>中表示参数类型。

实例:

// =========  action  ================
        public Action<Color> UpdateColor;
        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            Color color = Color.White;
            int index = comboBox2.SelectedIndex;
            switch (index)
            {
                case 0:
                    color = Color.Red;
                    break;
                case 1:
                    color = Color.Blue;
                    break;
                case 2:
                    color = Color.Black;
                    break;
                case 3:
                    color = Color.GreenYellow;
                    break;
            }
 
            UpdateColor = form2.SetColor;
            UpdateColor += form3.SetColor;
            UpdateColor(color);
        }

  Form2

public void SetColor(Color color)
{
     pictureBox1.BackColor = color;
     pictureBox1.Refresh();
}

Form3

public void SetColor(Color color)
{
     pictureBox1.BackColor = color;
     pictureBox1.Refresh();
}

 (3):Func

Func是有返回值的泛型委托

Func<int> 表示无参,返回值为int的委托

Func<object,string,int> 表示传入参数为object, string 返回值为int的委托

Func<object,string,int> 表示传入参数为object, string 返回值为int的委托

Func<T1,T2,,T3,int> 表示传入参数为T1,T2,,T3(泛型)返回值为int的委托

Func至少0个参数,至多16个参数,根据返回值泛型返回。必须有返回值,不可void

// =========  Func  ================
        /// <summary>
        /// func 委托,最后一个参数是返回值类型,之前的都是参数类型
        /// </summary>
        public Func<Color,string> func;
        private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
        {
            Color color = Color.White;
            int index = comboBox3.SelectedIndex;
            switch (index)
            {
                case 0:
                    color = Color.Red;
                    break;
                case 1:
                    color = Color.Blue;
                    break;
                case 2:
                    color = Color.Black;
                    break;
                case 3:
                    color = Color.GreenYellow;
                    break;
            }
            func = form2.SetColorFunc;
            func += form3.SetColorFunc;
            string res = func(color);
            label4.Text = res;
        }

Form2

public string SetColorFunc(Color color)
        {
            pictureBox1.BackColor = color;
            pictureBox1.Refresh();
            return "Form2 换色成功";
        }

Form3

      
  public string SetColorFunc(Color color)
        {
            pictureBox1.BackColor = color;
            pictureBox1.Refresh();
            return "Form3 换色成功";
        }

(4):predicate

泛型委托:表示定义一组条件并确定指定对象是否符合这些条件的方法。此委托由 Array  List 类的几种方法使用,用于在集合中搜索元素。

这个用的相对较少,可以被Func委托代替。

static void Main(string[] args)
        {
            Point[] points = { new Point(100, 200),
            new Point(150, 250), new Point(250, 375),
            new Point(275, 395), new Point(295, 450) };
            Point first = Array.Find(points, ProductGT10);
            Console.WriteLine("Found: X = {0}, Y = {1}", first.X, first.Y);
            Console.ReadKey();
        }
        private static bool ProductGT10(Point p)
        {
            if (p.X * p.Y > 100000)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

(5):委托清空

清空委托方法:

/// <summary>
        /// 清空委托方法一
        /// </summary>
        public void ClearDelegate(MethodDelegate delegateOnly)
        {
            while (delegateOnly != null)
            {
                delegateOnly -= delegateOnly;
            }
        }

(6):匿名委托:

采用匿名方法实例化的委托称为匿名委托。

每次实例化一个委托时,都需要事先定义一个委托所要调用的方法。为了简化这个流程,C# 2.0开始提供匿名方法来实例化委托。这样,我们在实例化委托时就可以 “随用随写” 它的实例方法。

使用的格式是:

委托类名 委托实例名 = delegate (args) {方法体代码} ;()args表示参数

这样就可以直接把方法写在实例化代码中,不必在另一个地方定义方法。当然,匿名委托不适合需要采用多个方法的委托的定义。

// =========  匿名委托  ================
        private void comboBox4_SelectedIndexChanged(object sender, EventArgs e)
        {
            Color color = Color.White;
            int index = comboBox4.SelectedIndex;
            switch (index)
            {
                case 0:
                    color = Color.Red;
                    break;
                case 1:
                    color = Color.Blue;
                    break;
                case 2:
                    color = Color.Black;
                    break;
                case 3:
                    color = Color.GreenYellow;
                    break;
            }
 
            // 这段委托执行的时候,出现了一个问题,就是委托不好用
            // 下边那行委托赋值,是不行的。因为,匿名委托也是相当于创建了一个委托。没创建完呢,就给自己赋值,是不行的。
            // 因此我们创建了一个委托之后,在下边用另一个委托给其赋值。是好用的
            MethodDelegate delegates = delegate(Color col)
            {
                Console.WriteLine("123");
                delegates = form2.SetColor;
            };
 
            // 匿名委托(先得有委托,才能匿名)
            MethodDelegate delegates2 = delegate (Color col)
            {
                delegates = form2.SetColor;
                delegates += form3.SetColor;
            };
            delegates2(color);
            delegates(color);
        }

 Form2

public void SetColor(Color color)
{
     pictureBox1.BackColor = color;
     pictureBox1.Refresh();
}

Form3

public void SetColor(Color color)
{
     pictureBox1.BackColor = color;
     pictureBox1.Refresh();
}

委托总结:

Delegate至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型

Func可以接受0个至16个传入参数,必须具有返回值

Action可以接受0个至16个传入参数,无返回值

Predicate只能接受一个传入参数,返回值为bool类型

匿名委托就那么回事,能用就用,不能用就用基本的就行。

这是C#委托的最基础的一些知识,以后遇到了再补充。

有好的建议,请在下方输入你的评论。

 

 

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

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

相关文章

【动手学深度学习】--15.含并行连结的网络GoogLeNet

文章目录 含并行连结的网络GoogLeNet1.Inception块2.GoogLeNet模型3.训练模型 含并行连结的网络GoogLeNet 学习视频&#xff1a;含并行连结的网络 GoogLeNet / Inception V3【动手学深度学习v2】 官方笔记&#xff1a;含并行连结的网络&#xff08;GoogLeNet&#xff09; 1.…

【智能交互】OPPO接入小布语音技能通关教程:个人开发者实现接口调用

目录 前言实际操作注册OPPO平台账号打开创建技能界面创建技能创建意图槽位解析对话管理对话测试接口代码编写接口创建新建意图对话管理测试猜想测试相关文档前言 适用人群:本教程适合大赛接入小布语音技能的同学以及初次使用小布助手的开发者 本篇文章是博主弄了多次测试才勉…

勒索花样繁多,“Sophos Encrypt”披马甲进行勒索攻击

近日&#xff0c;网络安全供应商Sophos发表声明&#xff0c;称Sophos被一款名为“Sophos Encrypt”新型勒索软件冒充&#xff0c;该勒索软件进行攻击时会冒用Sophos品牌名称&#xff0c;并将用户重要文件进行加密以勒索赎金。 现在的勒索软件类型多样&#xff0c;令企业防不胜防…

LeetCode·每日一题·874. 模拟行走机器人·哈希

作者&#xff1a;小迅 链接&#xff1a;https://leetcode.cn/problems/walking-robot-simulation/solutions/2350184/ha-xi-biao-zhu-shi-chao-ji-xiang-xi-by-x-20cg/ 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 著作权归作者所有。商业转载请联系作者获得授权&am…

【iPaaS干货分享】大型企业都在用的新一代SAP集成方式,你了解吗?

目录 目前企业实现SAP集成的主要方式 一、使用SAP PI/PO实现SAP与外部系统的集成 二、使用自开发方式 SAP新一代集成方式——基于iPaaS SAP连接器 一、分钟级实现SAP系统的集成 二、统一集成接口及安全管理 三、可视化编排改造SAP接口 SAP&#xff08;Systems, Applicatio…

GO语言方法集

实际上,这里 那为什么还要生产包装方法呢?主要是为了支持接口. 接口不能直接使用接收者为值类型的方法.因为我们A(a)接受者是第一个参数,而这个参数是动态派发的,参数放在栈的局部变量,编译器在编译阶段不能确定这个量的大小.而指针平台确定了大小也就确定了.面对这个问题,编译…

如何使用MATLAB软件完成生态碳汇涡度相关监测与通量数据分析

MATLAB MATLAB是美国MathWorks公司出品的商业数学软件&#xff0c;用于数据分析、无线通信、深度学习、图像处理与计算机视觉、信号处理、量化金融与风险管理、机器人&#xff0c;控制系统等领域。 [1] MATLAB是matrix&laboratory两个词的组合&#xff0c;意为矩阵工厂&a…

Java List集合 -- 最常用的两种排序方法

现在有一个类 public class Person {private int id;private int age;private String name;public Person(int id, int age, String name) {this.id id;this.age age;this.name name;}public int getId() {return id;}public int getAge() {return age;}public String getN…

149206-86-0,DOTA GGGA,双功能螯合物,修饰在多肽上的螯合剂

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ 规格单位&#xff1a;g |货期&#xff1a;按照具体的库存进行提供 | 纯度&#xff1a;95%| PART1-------试剂描述&#xff1a; 螯合剂Dota-ggga&#xff08;CAS号&#xff1a;149206-86-0&#xff09;&#xff0c;螯合…

skbuff.h在哪

今天看来下底层socket的实现&#xff0c;发现很多人都说有个skbuff结构&#xff0c;我就想着去找下这个&#xff0c; cat /include/linux/skbuff.h 结果找不到&#xff0c;查了下&#xff0c;需要下载内核源码 //Ubuntusudo apt install linux-headers-genericdpkg -S skbuff.…

Linux系统配置Node.js环境详细教程(图文讲解)

前言&#xff1a;在使用Jenkins部署Vue项目的时候&#xff0c;如果没有安装Node.js环境的话&#xff0c;Jenkins会无法对Vue项目进行构建&#xff0c;所以本期出了一篇关于在Linux系统如何配置Node.js环境的讲解&#xff0c;以博客的方式记录一下我详细的配置流程和踩过的坑&am…

包的使用及其创建

文章目录 前言类名冲突完整的类路径创建包导入类包总结 前言 java语言中&#xff0c;包在整个管理过程中发挥了重要的作用。使用包&#xff0c;可以有效地管理繁多的类文件&#xff0c;解决了类名重复的问题。在类中应用包和权限修饰符&#xff0c;可以控制他人对类成员的方法的…

旅游卡系统加盟代理软件开发

旅游行业的不断发展&#xff0c;越来越多的旅行社开始推出各种优惠卡来吸引游客。而随着智能手机的普及&#xff0c;开发一款旅行社优惠卡APP软件成为了一种必然的趋势。 该软件的主要功能是提供旅行社的各种优惠卡信息&#xff0c;包括优惠卡的种类、价格、使用范围、有效…

【代码随想录 | Leetcode | 第四天】数组 | 螺旋矩阵 | 螺旋矩阵 II

前言 欢迎来到小K的Leetcode|代码随想录|专题化专栏&#xff0c;今天将为大家带来螺旋矩阵的分享✨ 目录 前言59. 螺旋矩阵 II54. 螺旋矩阵总结 59. 螺旋矩阵 II 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n…

用微服务架构推进企业数字化转型升级

随着数字化转型进入深水区&#xff0c;企业应用程序建设需求急剧增长且变化多端&#xff0c;软件架构经历了单体结构、垂直架构、SOA架构&#xff0c;发展到了现在的微服务架构。 单体架构目前应用较多&#xff0c;部署容易&#xff0c;但单体式应用内部包含了所有需要的服务&…

四、DML-3.数据操作-删除

delete不能删除某个字段的值 若要删除某个字段的值&#xff0c;用update&#xff0c;将该字段设置为null 原数据表&#xff1a; 一、案例一 删除gender为女的员工 delete from employee where gender 女; 步骤一&#xff1a;输入delete命令并执行&#xff1a; 步骤二&#…

【Python】通过第三方库wxauto自动化操作微信电脑客户端

文章目录 一.简介二.wxauto提供的函数1.WxUtils类功能函数&#xff1a;2.WeChat类主要函数&#xff1a; 三.使用四.遇到的问题 一.简介 wxauto是一个Python第三方库&#xff0c;用于自动化操作微信电脑客户端通过wxauto&#xff0c;我们可以使用Python编写脚本&#xff0c;实现…

如何自学网络安全(黑客)

自学网络安全&#xff08;黑客&#xff09;需要掌握一系列的技能和知识&#xff0c;以下是一些学习网络安全的步骤&#xff1a; 基础知识&#xff1a;首先&#xff0c;你需要对计算机网络和操作系统有基本的了解。学习计算机网络的基本原理、网络协议和网络安全的基本概念。同时…

攻防世界-web-easytornado

题目描述&#xff1a;Tornado 框架。打开链接是一个简单的界面 1. 思路分析 看到有个/flag.txt&#xff0c;我们点击进去看下 发现传入了两个参数&#xff0c;一个是filename&#xff0c;还有一个是filehash 看到里面的内容&#xff0c;提示我们真正的flag在 /flllllllllllla…

报错 The server socket has failed to bind to [::] Pytorch中DDP中断训练报错

Pytorch中DDP &#xff1a;The server socket has failed to bind to [::]:29500 (errno: 98 - Address already in use&#xff09;_cv_lhp的博客-CSDN博客 报错如下 The server socket has failed to bind to [::]:999 (errno: 98 - Address already in use) 这个错误是因为…