首页 > 编程语言 >C# 中的委托与事件:实现灵活的回调机制

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

时间:2024-12-20 21:27:25浏览次数:6  
标签:Publisher 委托 publisher C# SomethingHappened 事件 回调 public

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#中委托和事件的文章对你有所帮助。如果有任何问题或需要进一步的信息,请随时告诉我!

标签:Publisher,委托,publisher,C#,SomethingHappened,事件,回调,public
From: https://blog.csdn.net/2302_82029124/article/details/144619993

相关文章

  • 【C++有点难】默认成员函数:构造函数
    默认成员函数有啥?总的来说嘞,有六种:构造函数,析构函数,拷贝构造函数,赋值重载函数,取地址重载函数其实我刚知道有六种的时候,也是很头大,但经过我不但地旁敲侧击,终于!我逐渐明白第一种:构造函数的神奇那学习之前,肯定要了解一下构造函数的概念吧?构造函数的概念:构造函数作为一种默认......
  • (2024.12)记录——Ubuntu20.04安装opencv库
    参考博文:Ubuntu20.04OpenCV详细安装教程(附多版本切换共存教程)_ubuntu20.04安装opencv-CSDN博客Ubuntu20.04上搭建OpenCV4.5.0&C++环境从源码构建1---下载官网地址:Releases-OpenCV选择需要的版本,点击Sources下载zip源码压缩包,下载后解压。2---编译过程1>安装工......
  • 题解:AT_arc008_3 [ARC008C] THE☆たこ焼き祭り2012
    思路看到$N\leq1000$,我们立马想到Floyd,把每个人都当作点,把传递小丸子所需的时间当作边权去建边。最后直接跑一遍Floyd就好了。AC代码#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;constintN=1e3+10;intx[N],y[N],t[N],r[N],n;doubled......
  • 用C#实现感知器算法——从零开始打造一个简单的机器学习模型!
    感知器(Perceptron)是一个经典的机器学习算法,常用于二分类问题。它是神经网络的基础,最早由FrankRosenblatt在1958年提出。今天,我们将用C#实现一个简单的感知器算法,让你理解感知器的工作原理,并能够亲自编码一个可用的模型。一、感知器算法概述感知器是一种线性分类器,其核心思想是......
  • C++面向对象
    目录C++核心类和对象对象特性友元运算符重载继承多态文件读写C++核心类和对象类和对象类和对象是C++面向对象的基础,在C++中万事万物都是对象,C++利用类来实例化对象,下面是创建一个Circle类并实例化的语法://创建类classCircle{public:intm_r;voidgetM_......
  • 对 Windows 备份 应用以及 WebExperienceHost 应用的删除和封装。具体来说,您提到删除
    对Windows备份应用以及WebExperienceHost应用的删除和封装。具体来说,您提到删除AppxManifest.xml文件中的WebExperienceHost应用和WindowsBackupClient.exe,这些操作通常用于定制和优化Windows系统,尤其是进行封装、去除不必要的系统应用或服务。以下是详细步骤及说明,......
  • C++STL与泛型编程
    目录C++提高编程模版STL初识StringVectorDequeStackQueueListSetPairMap其它函数对象谓词STL常见算法遍历算法查找算法排序算法拷贝和替换算法算术生成算法常见集合算法C++提高编程本阶段主要针对C++泛型编程和STL技术做详细讲解模版C++另一种编程思想称为泛型编程,主要利用......
  • Get-WmiObject -Class Win32_SystemEnclosure -Namespace "root\CIMV2" | Select-Obj
    Get-WmiObject-ClassWin32_SystemEnclosure-Namespace"root\CIMV2"|Select-ObjectChassisTypes这条PowerShell命令用于查询计算机的硬件外壳(Chassis)信息,特别是返回系统机箱类型(ChassisTypes)。解释命令的组成部分:Get-WmiObject:这是一个用于查询WindowsManagement......
  • 题解:CF917A The Monster
    思路分别枚举连续子序列所有起点的可能。用变量来记录左括号和右括号的数量,左括号\(+1\),右括号\(-1\)。对于问号,则通过当前左括号和右括号的数量来判断应该变为右括号还是变为左括号。当右括号数量大于左括号数量时,就可以停止枚举以当前起点为起点的连续子序列了,因为无论怎......
  • 题解:CF603A Alternative Thinking
    思路你猜这个题为什么是A题?很思维的解法。只允许翻转一次,所以最多只会在原答案上加\(2\)。所以我们来讨论仅有的三种可能:加\(2\),要有两段连续的\(0\)或\(1\)。加\(1\),要有一段连续的\(0\)或\(1\)。不加,没有连续的\(0\)或\(1\)。我们的代码模拟上面的三种......