C# 中的委托与事件:实现灵活的回调机制

C#中的委托(Delegate)和事件(Event)。委托和事件是C#中非常重要的特性,它们允许你实现回调机制和发布-订阅模式,从而提高代码的灵活性和解耦程度。通过使用委托和事件,你可以编写更加模块化和可扩展的应用程序。以下是一篇关于C#中委托和事件的文章。


引言

委托(Delegate)和事件(Event)是C#中非常重要的特性,它们允许你实现回调机制和发布-订阅模式,从而提高代码的灵活性和解耦程度。通过使用委托和事件,你可以编写更加模块化和可扩展的应用程序。本文将详细介绍C#中的委托和事件,包括其基本概念、使用方法和应用场景。

委托的基本概念

什么是委托?

委托是一种类型安全的函数指针,它允许你将方法作为参数传递给其他方法。委托定义了一个方法签名,任何符合该签名的方法都可以被委托实例引用。

定义委托

可以通过 delegate 关键字来定义委托类型。

public delegate void NotifyHandler(string message);

使用委托

定义了委托后,可以在类中声明委托类型的字段或属性,并在需要时调用委托。

public class Notifier
{public event NotifyHandler OnNotify;public void TriggerNotification(string message){OnNotify?.Invoke(message); // 调用所有订阅者}
}public class Subscriber
{public Subscriber(Notifier notifier){notifier.OnNotify += HandleNotification;}private void HandleNotification(string message){Console.WriteLine($"Received notification: {message}");}
}// 使用委托
var notifier = new Notifier();
var subscriber = new Subscriber(notifier);notifier.TriggerNotification("Hello, World!");

内置委托类型

C# 提供了一些内置的委托类型,如 ActionFunc,它们简化了常见的委托定义。

Action 委托

Action 是一个没有返回值的委托,可以接受多个输入参数。

Action<string> printAction = Console.WriteLine;
printAction("Hello, World!");

Func 委托

Func 是一个有返回值的委托,可以接受多个输入参数。

Func<int, int, int> addFunc = (a, b) => a + b;
Console.WriteLine(addFunc(3, 5)); // 输出: 8

事件的基本概念

什么是事件?

事件是一种特殊的委托,它允许对象通知其他对象发生了某些事情。事件通常用于实现发布-订阅模式,使得代码更加解耦和模块化。

定义事件

事件基于委托类型定义,通常使用 event 关键字来声明。

public class Publisher
{public event EventHandler<EventArgs> SomethingHappened;protected virtual void OnSomethingHappened(){SomethingHappened?.Invoke(this, EventArgs.Empty);}public void DoSomething(){// 模拟发生某件事情OnSomethingHappened();}
}public class Subscriber
{public Subscriber(Publisher publisher){publisher.SomethingHappened += Publisher_SomethingHappened;}private void Publisher_SomethingHappened(object sender, EventArgs e){Console.WriteLine("Something happened!");}
}// 使用事件
var publisher = new Publisher();
var subscriber = new Subscriber(publisher);publisher.DoSomething(); // 触发事件

自定义事件参数

为了传递更多信息,可以创建自定义的事件参数类,继承自 EventArgs

public class CustomEventArgs : EventArgs
{public string Message { get; set; }
}public class Publisher
{public event EventHandler<CustomEventArgs> SomethingHappened;protected virtual void OnSomethingHappened(CustomEventArgs e){SomethingHappened?.Invoke(this, e);}public void DoSomething(string message){OnSomethingHappened(new CustomEventArgs { Message = message });}
}public class Subscriber
{public Subscriber(Publisher publisher){publisher.SomethingHappened += Publisher_SomethingHappened;}private void Publisher_SomethingHappened(object sender, CustomEventArgs e){Console.WriteLine($"Publisher says: {e.Message}");}
}// 使用自定义事件参数
var publisher = new Publisher();
var subscriber = new Subscriber(publisher);publisher.DoSomething("Hello, World!"); // 触发事件并传递信息

应用场景

用户界面交互

事件广泛应用于用户界面组件之间通信,例如按钮点击、文本框输入等。

button.Click += (sender, e) => MessageBox.Show("Button clicked!");

数据绑定

事件可用于数据绑定,当数据源发生变化时触发更新。

dataSource.PropertyChanged += (sender, e) => UpdateUI();

日志记录

事件可以用来实现日志记录功能,当某个操作完成时记录相关信息。

logger.Logged += (sender, e) => WriteLogToFile(e.Message);

结论

通过使用委托和事件,可以实现灵活的回调机制和发布-订阅模式,从而提高代码的灵活性和解耦程度。委托提供了一种类型安全的方式将方法作为参数传递,而事件则允许对象通知其他对象发生了某些事情。希望本文能够帮助你更好地理解和应用C#中的委托和事件技术。如果你有任何疑问或需要进一步的信息,请随时留言讨论!


希望这篇关于C#中委托和事件的文章对你有所帮助。如果有任何问题或需要进一步的信息,请随时告诉我!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络安全(3)_安全套接字层SSL

4. 安全套接字层 4.1 安全套接字层&#xff08;SSL&#xff09;和传输层安全&#xff08;TLS&#xff09; &#xff08;1&#xff09;SSL/TLS提供的安全服务 ①SSL服务器鉴别&#xff0c;允许用户证实服务器的身份。支持SSL的客户端通过验证来自服务器的证书&#xff0c;来鉴别…

【ArcGIS Pro】水文水资源、水生态与水环境

ArcGIS Pro 是一款集数据采集、处理、分析和可视化于一体的强大 GIS 工具&#xff0c;广泛应用于水文、水资源、水生态和水环境等领域。其全面的功能使得研究人员能够高效地处理各种水文和环境数据&#xff0c;从而为科学研究和决策支持提供强有力的技术保障。在水文分析方面&a…

【前端系列】Element-UI 悟道

???欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老…

中软高科身份证云解码金融(银行)解决方案介绍

多年来&#xff0c;中软高科一直深耕身份证云解码领域&#xff0c;对身份证云解码应用于金融&#xff08;银行&#xff09;&#xff0c;进行了大量且深入的研究。从长期调研来看&#xff0c;金融&#xff08;银行&#xff09;的痛点需求主要有&#xff1a; 传统身份证解码设备…

【LeetCode】每日一题 2024_12_19 找到稳定山的下标(模拟)

前言 每天和你一起刷 LeetCode 每日一题~ 最近力扣的每日一题出的比较烂&#xff0c;难度过山车&#xff0c;导致近期的更新都三天打鱼&#xff0c;两天断更了 . . . LeetCode 启动&#xff01; 题目&#xff1a;找到稳定山的下标 代码与解题思路 先读题&#xff1a;最重要…

SpringBoot开发——详解Tomcat线程池默认最大支持200并发

文章目录 1、SpringBoot 应用可以同时并发处理多少请求2、Tomcat线程池3、底层源码3.1 runWorker3.2 workQueue.offer 4、总结 1、SpringBoot 应用可以同时并发处理多少请求 Q&#xff1a;经典面试题&#xff0c;SpringBoot 应用可以同时并发处理多少请求&#xff1f; A&#…

Linux限制root 用户的远程登录(安全要求)

前言&#xff1a;现在基本用户主机都不允许使用root来操作&#xff0c;所以本文通过创建新用户&#xff0c;并限制root用户的ssh来解决这个问题 1. 创建新账户 aingo 首先&#xff0c;使用 root 账户登录系统。 sudo useradd aingo设置 aingo 账户密码&#xff1a; sudo pa…

计算机网络之王道考研读书笔记-2

第 2 章 物理层 2.1 通信基础 2.1.1 基本概念 1.数据、信号与码元 通信的目的是传输信息。数据是指传送信息的实体。信号则是数据的电气或电磁表现&#xff0c;是数据在传输过程中的存在形式。码元是数字通信中数字信号的计量单位&#xff0c;这个时长内的信号称为 k 进制码…

谁说C比C++快?

看到这个问题&#xff0c;我我得说&#xff1a;这事儿没有那么简单。 1. 先把最大的误区打破 "C永远比C快" —— 某位1990年代的程序员 这种说法就像"自行车永远比汽车省油"一样荒谬。我们来看个例子&#xff1a; // C风格 char* str (char*)malloc(100…

【Unity3D】无限循环列表(扩展版)

基础版&#xff1a;【Unity技术分享】UGUI之ScrollRect优化_ugui scrollrect 优化-CSDN博客 using UnityEngine; using UnityEngine.UI; using System.Collections.Generic;public delegate void OnBaseLoopListItemCallback(GameObject cell, int index); public class BaseLo…

Hive SQL 查询所有函数

-- 显示所有的函数 show functions; -- 对函数year进行解释 desc function year; -- 对函数year进行详细解释&#xff0c;并举例说明 desc function extended year;– 对函数year进行解释 desc function year; – 对函数year进行详细解释&#xff0c;并举例说明 desc functio…

Android13 系统签名应用编译调试说明

Android13 系统签名应用编译调试说明 文章目录 Android13 系统签名应用编译调试说明一、前言二、系统签名应用调试步骤1、新建一个应用&#xff0c;确保可以正常编译出APK2、获取系统签名文件3、Android Studio 编译安装系统权限应用&#xff08;1&#xff09;导入签名文件生成…

基于Spring Boot的医院质控上报系统

一、系统背景与意义 医院质控上报系统旨在通过信息化手段&#xff0c;实现医院质量控制的标准化、流程化和自动化管理。该系统能够帮助医院实时监控医疗质量数据&#xff0c;及时发现和处理潜在的质量问题&#xff0c;从而确保医疗服务的安全性和有效性。同时&#xff0c;系统…

将java项目部署到linux

命令解析 Dockerfile: Dockerfile 是一个文本文件&#xff0c;包含了所有必要的指令来组装&#xff08;build&#xff09;一个 Docker 镜像。 docker build: 根据 Dockerfile 或标准指令来构建一个新的镜像。 docker save: 将本地镜像保存为一个 tar 文件。 docker load: 从…

LeetCode:226.翻转二叉树

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;226.翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 …

Webpack学习笔记(2)

1.什么是loader? 上图是Webpack打包简易流程&#xff0c;webpack本身只能理解js和json这样的文件&#xff0c;loader可以让webpack解析其他类型文件&#xff0c;并且将文件转换成模块供我们使用。 test识别出那些文件被转换&#xff0c;use定义转换时使用哪个loader转换 上图…

【WebDriver】浏览器驱动下载及其配置

一、Windows电脑环境搭建-Chrome浏览器 行业内&#xff0c;Chrome (谷歌) 浏览器对于自动化程序来讲是比较稳定的. 自动化程序推荐使用 Chrome 浏览器的原因有几个&#xff1a; 开发者工具&#xff1a;Chrome 提供强大的开发者工具&#xff0c;方便调试和测试自动化脚本。 稳…

list使用

目录 list介绍 list使用 list创建 list迭代器 容量操作 元素访问 修改元素 其他操作 list介绍 ● list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代 ● list的底层是双向链表结构&#xff0c;双向链表中每个元素存…

【AIGC】如何高效使用ChatGPT挖掘AI最大潜能?26个Prompt提问秘诀帮你提升300%效率的!

还记得第一次使用ChatGPT时&#xff0c;那种既兴奋又困惑的心情吗&#xff1f;我是从一个对AI一知半解的普通用户&#xff0c;逐步成长为现在的“ChatGPT大神”。这一过程并非一蹴而就&#xff0c;而是通过不断的探索和实践&#xff0c;掌握了一系列高效使用的技巧。今天&#…

windows 使用python共享网络给另外一个网卡

# -*- coding: utf-8 -*- import subprocessdef open_share(to_shared_adapter, from_shared_adapter):"""打开以太网的网络共享:return: None"""powershell_script f"""# Register the HNetCfg library (once)# regsvr32 hnetc…