懂了委托,才算真正入门C#

news2024/12/23 11:57:45

文章目录

    • 委托的概念
    • 多播委托
    • 拖动按钮

前文提要:

  • 超快速成,零基础掌握C#开发中最重要的概念
  • 抽丝剥茧,C#面向对象快速上手
  • Winform,最友好的桌面GUI框架

委托的概念

委托这个名字取的神乎其神的,但实质是函数式编程,把函数作为参数传递给另一个参数。对于C语言程序员来说,就是把函数指针当作参数传递给另一个函数。

唯一需要注意的是,C#毕竟是强类型语言,用于委托的函数,也相当于变成了一种可以被传递的变量,所以在创建以及调用之前,需要声明其数据类型

delegate int Op(int a, int b);

这个委托是一种需要传入两个整型参数的函数,返回值也是整数。接下来对这个委托进行实例化,最终代码如下

int add(int a, int b)
{
    return a + b;
}

var addTest = new Op(add);
void calc(Op func, int a, int b)
{
    Console.WriteLine($"func({a},{b})={func(a,b)}");
}

calc(addTest, 2, 3);
delegate int Op(int a, int b);

事先说明一下,本文所有代码均在.Net6的顶级语句中实现,顶级语句需要把delegate声明放在最下面。

其中,add是一个十分质朴的函数,没什么可说的;addTest是一个内置了addOp对象,其功能与add是相同的。

calc是一个以Op对象为参数的函数,在这个函数中,通过Op对象func,计算了另外两个参数ab

最后,调用了calc函数,将addTest作为参数,实质上是计算了add(2,3),并打印了这个结果。

func(2,3)=5

>“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

多播委托

所谓多播委托,就是一个委托中通过+=运算符添加多个函数。当然也可以通过-=运算符将原本添加的函数删除掉。

为了演示这个功能,将上述代码稍作更改。

int add(int a, int b){
    Console.WriteLine($"{a}+{b}={a+b}");
    return a + b;
}

int minus(int a, int b){
    Console.WriteLine($"{a}-{b}={a-b}");
    return a-b;
}

void calc(Op func, int a, int b)
{
    func(a,b);
}

Op opTest = add;
opTest += minus;
opTest += add;
opTest += minus;
calc(opTest, 3, 4);
Console.WriteLine("减去一个minus");
opTest -= minus;
calc(opTest, 3, 4);

delegate int Op(int a, int b);

其中Op opTest=add的写法等价于Op opTest = new OpTest(add),但若省略new,则不可写为var opTest = add,这个时候没法进行类型推断。

输出结果为

3+4=7
3-4=-1
3+4=7
3-4=-1
减去一个minus
3+4=7
3-4=-1
3+4=7

由此可知,委托在调用的时候,会按照+=的先后顺序调用函数,并将最后一个调用的函数作为返回值。

而函数在委托中以栈的方式存放,-=会先减去后存入委托中的函数。

拖动按钮

源码地址:拖动按钮

多播委托在GUI编程中最为常用,尤其是拖动控件时。拖动控件的流程包括三个步骤

  1. 鼠标点击控件
  2. 鼠标拖动控件
  3. 鼠标松开控件

则对于一个控件来说,其绑定的事件会随着鼠标的点击情况而发生变化
0. 鼠标未点击时,控件需要响应鼠标点击事件

  1. 鼠标点击之后,控件需要响应鼠标拖动、鼠标松开的事件
  2. 鼠标拖动时,控件响应的事件并不发生变化
  3. 鼠标松开后,控件需要解绑拖动以及松开事件

接下来,实操一下,简单起见,GUI采用winForm,在新建项目之后,拖动一个按钮到窗口上,右键按钮->属性,可以更改一下名字和内容,然后点击右下角属性栏的小闪电,然后注册MouseDown事件,输入btnTest_MouseDown并按下回车之后,IDE会自动来到代码界面,并出现一个空的委托函数。

private void btnTest_MouseDown(object sender, MouseEventArgs e)
{

}

为了理解这个东西的作用,可以在解决方案资源管理器中找到Form1.Designer.cs文件,点进去之后可以看到下面这行代码

this.btnTest.MouseDown += new System.Windows.Forms.MouseEventHandler(this.btnTest_MouseDown);

换言之,btnTest.MouseDown就是一个多播委托,刚刚我们的行为,为其注册了一个名为btnTest_MouseDown的实现,尽管这个实现现在还是空的。

若想拖动一个控件,第一步就是按下鼠标,按下鼠标之后,需要再注册两个委托,分别再拖动鼠标和松开鼠标时起作用;而松开鼠标和按下鼠标的作用刚好相反,要求取消注册拖动事件,所以下面分别实现这三个功能。

private void btnTest_MouseDown(object sender, MouseEventArgs e)
{
   btnTest.MouseMove += btnTest_MouseMove;
   btnTest.MouseLeave += btnTest_MouseLeave;
}
private void btnTest_MouseLeave(object sender, EventArgs e)
{
   btnTest.MouseMove -= btnTest_MouseMove;
   btnTest.MouseLeave -= btnTest_MouseLeave;
}
private void btnTest_MouseMove(object sender, MouseEventArgs e)
{
   int dh = btnTest.Height / 2;
   int dw = btnTest.Width / 2;
   btnTest.Top = MousePosition.Y - this.Top - dh;
   btnTest.Left = MousePosition.X - this.Left - dw;
}

上面需要注意一点,MouseLeaveMouseMove, MoseDown是不同类型的委托,故而创建函数的参数类型是不同的。

btnTest.Top为按钮顶端距离窗口顶端的距离;MousePosition.Y表示鼠标距离屏幕顶端的距离;this.Top表示窗口顶端距离屏幕顶端的位置,最后再减去一个按钮高度的一半,相当于是把按钮的中心移动到鼠标光标处。这种逻辑过于简单粗暴,实际工作时不会用到,之所以这么写是因为简单。

效果如下

在这里插入图片描述

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

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

相关文章

网络攻防技术--第五次作业

文章目录作业五一、 什么是恶意代码?恶意代码主要类型有哪些?二、 恶意代码的基本技术主要包括哪几种?三、 什么是特洛伊木马?有什么特点?四、 什么是计算机病毒?其有哪几个基本组成部分?五、 什…

项目管理工具能做什么 它给企业带来哪些作用

一个项目经理,如果要想管理好项目,那么一定要掌握项目管理的方法与工具。在项目管理过程中总会借助一些工具来掌控项目点点滴滴,这不仅可以提高团队的生产力和效率,还可以让项目组织在不同项目带来的影响变化中做好准备。 项目管…

每天一道大厂SQL题【Day03】订单量统计

每天一道大厂SQL题【Day03】订单量统计 大家好,我是Maynor。相信大家和我一样,都有一个大厂梦,作为一名资深大数据选手,深知SQL重要性,接下来我准备用100天时间,基于大数据岗面试中的经典SQL题&#xff0c…

SAP 自定义SQL编辑器

导语:自定义SQL编辑器,可使用SAP ABAP的OPEN SQL语法进行编辑,快速出具简单报表,基本具备与SAP中DB02相似的功能。 此资源其中有两个版本,一个版本是网上的代码资料,另一个版本是本人优化过后的&#xff0…

Gerrit3.4.1安装使用

环境依赖jdk11 安装jdk11: 下载: wget https://download.java.net/openjdk/jdk11/ri/openjdk-1128_linux-x64_bin.tar.gz解压: tar zxvf openjdk-1128_linux-x64_bin.tar.gzsudo update-alternatives --install /usr/bin/java java /home/je…

Fiddler抓包工具配置+Jmeter基本使用

目录 一、Fiddler抓包工具的配置和使用 局域网络配置# Fiddler配置# Fiddler抓包实例# 二、Jmeter的基本使用 Jmeter的安装配置# 第一个Jmeter脚本# 一、Fiddler抓包工具的配置和使用 在编写网关自动化脚本之前,得先学会如何抓包,这里以Fiddler为…

Docker容器及安装 01

前言 1.1 从环境配置说起 环境配置是软件开发的一大难题。开发、测试及运维人员需要相同的代码运行环境,如此一来就需要多次搭建环境,想想就觉得麻烦,实际上,在不了解docker等容器技术以前,还真就是这么干的&#xff…

2023年FOF/MOM基金研究报告

第一章 概况 FOF 是 Fund of Funds 的简称,即“基金中的基金”,是一种专门投资于其他投资基金的基金。FOF 并不直接投资股票或债券,其投资范围主要限于其他基金。按照募集方式,FOF 分为公募 FOF 和私募 FOF。 公募 FOF 是指将80…

python小游戏——飞机大战代码开源

♥️作者:小刘在这里 ♥️每天分享云计算网络运维课堂笔记,努力不一定有收获,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的,绽放,愿所有的美好&#…

明细打印重影方案

一、问题描述生产上出现明细查询打印业务,部分客户打印数据时出现数据重叠现象,不利于客户使用,影响客户体验。二、问题原因对方户名公司名称字段目前没有限制,按照现有的分页处理机制,如果一页纸出现多个公司名称较长…

python中值传递、引用传递、global关键字

结论1、函数中,数值、字符、元组的传递是值传递 b 5 print(id b ,id(b))def change(b):print(\n)#print(在函数change中 修改前 id b ,id(b))b 0print(在函数change中 修改后 id b ,id(b))def print_b():print(\n)print(在函数print b中 b , b)print(在函数pri…

【C++修炼之路】C++入门(下)

👑作者主页:安 度 因 🏠学习社区:StackFrame 📖专栏链接:C修炼之路 文章目录一、前言二、内联函数1、概念2、特性三、auto(C 11)1、概念2、价值3、三个不能四、范围for循环(C11)1、基本使用2、使…

MySQL基础(3)—— MySQL数据类型

文章目录数值类型1、整数类型2、浮点数类型3、定点数类型日期和时间类型1、YEAR2、DATE、TIME、DATETIME3、TIMESTAMP字符串类型1、CHAR(M)2、VARCHAR(M)3、各种 TEXT 类型4、ENUM 类型和 SET 类型二进制类型1、BIT 类型2、BINARY(M) 与 VARBINARY(M)3、BLOB 类型MySQL说到底就…

移动出行2023:聊以新颜待今朝

兔年春节期间,城市再现浓浓烟火气。预订全满的年夜饭、排不到号的奶茶店以及火爆的电影票房等,证明着“吃、游、购、娱”等需求集中释放的“威力”。根据国家税务总局发布的最新数据,今年春节假期,全国消费相关行业销售收入与上年…

最长上升子序列问题(LIS问题)与最长不上升子序列问题的四种方法(c++ 模板代码)

文章目录动态规划树状数组线段树二分查找最大上升子序列问题也叫做LIS问题,与最大公共子序列LCS问题是一类经典问题,在本章我们将总结一下求解LIS最大上升子序列的几种方法,同时也会给出对应的最大不上升子序列的求解方法。 关于LCS问题&…

【表格单元格可编辑】vue-elementul简单实现table表格点击单元格可编辑,点击单元格变成输入框修改数据

前言 这是最近遇到的功能,经常会需要一个表格可以编辑数据 类似于excel那种点击一下单元格就可以编辑数据,修改后鼠标移动出去 光标消失就会保存数据给后台 这里记录一下实现方法,其实也比较简单 就是通过角标来判断显示隐藏的 效果图 代码…

[Android开发基础4] 点击事件的响应与处理

文章目录 方法一:控件的onClick属性 方法二:内部类 方法一:控件的onClick属性 利用控件自带的onClick属性,指定事件处理函数名称即可实现控件点击事件的处理 这里有个小技巧就是当设置完控件的onClick属性后,它会报没…

XXE漏洞常见利用点总结

目录 知识点小结 常用payload 本地文件读取 SSRF 引入外部实体 dtd 信息探测 XXE漏洞攻击 案例演示 案例一(有回显) 案例二(无回显读取本地敏感文件(Blind OOB XXE)) XXE 防御 使用语言中推荐的禁用外部实体的方法 知…

08-linux网络管理-iftop命令详解

文章目录1. 安装2. 基本使用2.1 命令2.2 输出2.3 说明3. 选项3.1 选项说明3.2 几个示例-n(不查找主机名)-i (查看指定网卡流量)-P(显示主机端口)-t(不使用ncurses 界面)4. ncurses界…

IDEA集成Docker插件实现一键自动打包部署

一. 概述 大家部署项目的时候,动辄十几个服务,每次修改逐一部署繁琐不说也会浪费越来越多时间,所以本篇整理通过一次性配置实现一键部署微服务,直接上教程。 二. 配置服务器 1、Docker安装 服务器需要安装Docker,如…