【C#小知识】c#中的delegate(委托)和event(事件)

今天来介绍一下delegate和event。delegate在c#中可以定义一个函数类型,可以将函数作为一个对象来使用。event在c#中则可以看做一个函数的集合,event中包含了一个或多个函数。

delegate

using System;

public class MyClass
{
    //定义委托
    public delegate void EventHandler(string pParameter);
    //委托对象
    public EventHandler handler = null;

    public void Main()
    {
        handler = TestFunction;
        handler("Hello World");
    }

    private void TestFunction(string pParameter)
    {
        Console.WriteLine("pParameter is " + pParameter);
    }
}

如上代码,定义委托关键字“delegate”,委托的定义包含委托返回值、委托名称、委托参数。定义了委托类型之后,就可以声明委托对象了。EventHandler就是定义的委托类型,handler则是声明的委托对象。

在使用过程中就可以将函数TestFunction赋值给handler,这里需要注意的是委托的返回值和参数必须和赋值函数的返回值和参数一致,否则编译器则会提示错误。在使用时像普通的函数调用一样使用即可。

event

using System;

public class MyClass
{
	public delegate void EventHandler(string pParameter);

	public event EventHandler handler = null;

	public void Main()
	{
		handler += HelloWorld;
		handler += GoodMorning;
		handler("");
		handler -= GoodMorning;
		handler?.Invoke("");
        /*输出结果
         * This is HelloWorld
         * This is GoodMorning
         * This is HelloWorld
        */
	}

	private void HelloWorld(string pParameter)
	{
		Console.WriteLine("This is HelloWorld");
	}

	private void GoodMorning(string pParameter)
	{
		Console.WriteLine("This is GoodMorning");
	}
}

如上代码,使用关键字“event”来定义事件,这里的handler已经不是委托对象了,而是事件对象,事件的类型依然是委托类型。和委托对象不同,事件对象可以包含多个函数,通过+=运算符来进行添加函数。如果需要从事件中去除某个函数,则可以通过-=运算符来移除函数。

事件除了可以像普通函数一样通过()括号的方式调用,也可以通过Invoke方法进行调用。作者个人比较喜欢用Invoke方法进行调用,这样可以使用条件运算符“?”来进行判断事件是否为空。

官方文档连接

delegate文档连接:https://learn.microsoft.com/zh-cn/dotnet/csharp/delegate-class

event文档连接:https://learn.microsoft.com/zh-cn/dotnet/csharp/programming-guide/events/how-to-subscribe-to-and-unsubscribe-from-events


相关文章

  • C# 实现网页内容保存为图片并生成压缩包

    通过动态页面技术,可以实现简历配置后的网页内容输出,但制作对应的各种模板会遇到开发效率和服务跟进的问题。为了保障原样输出,折中而简单的方案就是将动态输出的页面转化为图片格式。

  • 五种多目标优化算法(MSSA、MOJS、NSWOA、MOPSO、MOAHA)性能对比(提供MATLAB代码)

    多目标优化算法是用于解决具有多个目标函数的优化问题的一类算法。其求解过程可以分为以下几个步骤:1. 定义问题:首先需要明确问题的目标函数和约束条件。多目标优化问题通常涉及多个目标函数,这些目标函数可能是相互矛盾的,因此需要进行权衡和平衡。2. 生成初始解集:通过某种方式生成初始解集,可以是随机生成、根据经验生成或者使用已有的解集。3. 评估解集:对初始解集中的每个解进行评估,计算其在各个目标函数上的值。评估方法可以根据具体问题选择,例如计算目标函数值、计算约束违反程度等。

  • C#使用重载方法实现不同类型数据的计算

    为了避免异常,可以先使用Decimal.Parse(string)方法将字符串转换为小数,然后再使用Convert.ToInt32(decimal)方法将小数转换为整数。如果一个类中存在两个以上的同名方法,并且方法的参数类型、个数或者顺序不同,当调用这样的方法时,编译器会根据传入的参数自动进行判断,决定调用哪个方法。例如,字符串是"123.456",包含非数字字符"."。重载方法就是方法名称相同,但是每个方法中参数的数据类型、个数或顺序不同的方法。如果字符串包含非数字字符,例如小数点,该方法将引发异常。

  • Makefile 和 Bash 脚本之间区别和联系

    在 Makefile 中可以调 Bash 脚本,或在 Makefile 中直接写入 Bash 命令。这使得在构建过程中执行更复杂的任务成为可能。Makefile和Bash脚本由于它们的设计目标和用途不同,它们在基本结构、命令执行、通配符使用、错误处理等方面存在显著的差异。了解这些差异对于正确编写和理解Makefile和Bash脚本至关重要。Makefile主要用于编译和构建软件项目,而Bash脚本则更广泛地应用于系统管理和自动化任务。在实际工作中,两者可以结合使用,以创建一个完整、自动化的构建和部署。

  • C#:Sleep() 和 Wait() 有什么区别

    Sleep() 和 Wait() 是两个不同的方法,用于控制线程的执行。

  • DockerUI如何部署结合内网穿透实现公网环境管理本地docker容器

    DockerUI是一个docker容器镜像的可视化图形化管理工具。DockerUI可以用来轻松构建、管理和维护docker环境。它是完全开源且免费的。基于容器安装方式,部署方便高效,浏览和维护docker单节点或集群节点worker和manager。DockerUI具有易于使用的界面。它不需要记住 docker 指令。只需下载镜像即可立即加入并完成部署。使用DockerUI并结合cpolar内网穿透可以更加轻松的管理docker和swarm,实现后台公网访问并管理,视觉性更加直观,后台开发更加便利。

  • C++ STL库详解:容器适配器stack和queue的结构及功能

    详细介绍了c++中的stack和queue两大容器适配器的功能、接口与使用方法,通过与vector、string等容器的配合使用来实现特定的功能。介绍了stack与queue的底层默认容器deque的原理及结构以及它的优缺陷。

  • C语言——深入理解指针(1)

    我们已经知道,32内存位计算器有32条地址总线,每条线有1和0两个状态,那么一个内存的编号就有32条地址线表示,一条地址线占一个比特位,那么32条地址线就是32个比特位,因此就是4个字节。,可以这么理解,32位的计算器有32条这样的线,每个线有两种状态,分别是0和1,那么32根线一共能表示2^32种状态,这样的每个状态就是我们的一个地址,他们分别储存在不同的硬件上,地址信息被下达给内存,在内存上,就可以找到该地址对应的数据,将数据在通过数据总线传入CPU内寄存器。当然,需要我们了解一下计算机的进制转换,

  • C,C++,C# 的区别

    C#是一种面向对象的编程语言,由微软开发。总的来说,C适合系统级编程和嵌入式开发,C++适合大型项目和需要高性能的应用程序开发,而C#适合Windows应用程序开发和.NET平台。C++是一种面向对象的编程语言,是C的扩展。C++也具有更强大的标准库,以支持更多的功能和任务。它具有简单的语法和较小的标准库,适合于高效的低级编程和处理底层细节。C++具有更高的性能和更好的底层控制能力,但开发过程中更复杂。C#的开发速度更快,代码更易于维护,但性能可能稍逊于C++。C,C++,C# 是三种不同的编程语言。

  • 一些著名的软件都用什么语言编写?

    比如你的两个朋友与你分别玩用VB、Java、与C++编写的“跑跑卡丁车”,你玩C++编写的游戏已经跑玩结束了,发现你的两个朋友还没开始跑呢,那是相当的卡啊。备注:曾经在智能手机的操作系统(Windows Mobile)考虑掺点C#写的程序,比如软键盘,结果因为写出来的程序太慢,实在无法和别的模块合并,最终又回到C++重写。:2008 年推出:C语言(有传言说是用Java开发的操作系统,但最近刚推出原生的C语言SDK): 部分JAVA(对外接口),主要为C++ (开源,可下载其源代码)

  • C# 十大排序算法

    这些排序算法具有不同的时间复杂度、空间复杂度和稳定性,适用于不同的排序场景。每种算法都有其独特的思想和实现方式,您可以根据具体的需求选择适合的排序算法。以上代码分别实现了10大算法。请注意,如果需要对其他类型的数据进行排序,需要进行相应的修改。

  • Java编程模型:VO,BO,PO,DO,DTO

    Java编程模型中的VO,BO,PO,DO,DTO提供了一种结构化和组织代码的方法。通过合理运用这些概念,可以使代码更具可读性、可维护性和可扩展性。在实际项目中,根据需求和架构设计,合理选择和运用这些概念将有助于构建清晰、高效的Java应用程序。