c#中的事件和委托

委托

我们先来说说委托的使用和语法,然后再说概念

声明一个委托变量,这个委托可以在类外面,命名空间内,范围很广泛

cs 复制代码
using System;

namespace ConsoleApp1
{
    //声明一个委托,无返回值带参数的
    public delegate void sayHelloDlg(string name);
    class Program
    {
        private static void Main(string[] args)
        {
            
        }
          
    }
}

声明一个委托后,我们还是写一个对应的方法,才能给他赋值,这个方法的返回值和参数格式都要和委托一致

cs 复制代码
using System;

namespace ConsoleApp1
{
    //声明一个委托,无返回值带参数的
    public delegate void sayHelloDlg(string name);
    class Program
    {
        private static void Main(string[] args)
        {
            
        }
        //委托对应的函数
        public static void sayHello(string name)
        {
            Console.WriteLine($"{name},你好呀");
        }
    }
}

之后我们可以对其赋值,调用,执行之后控制台会输出(张三,你好呀)

cs 复制代码
private static void Main(string[] args)
{
    //委托赋值的方法必须返回值和参数的格式一致
    //将方法以变量的形式传递,并且以方法的形式执行,多数用于回调函数
    sayHelloDlg dlg = new sayHelloDlg(sayHello);
    dlg("张三");
    Console.ReadKey();
}

除此之外呢,还有委托链,即一个委托可以绑定多个方法

通过+=和-=来操作委托链

或者Delegate.Combine(事件, 新的方法)和Delegate.Remove(事件, 要删除的方法);

cs 复制代码
private static void Main(string[] args)
{
    //委托赋值的方法必须返回值和参数的格式一致
    //将方法以变量的形式传递,并且以方法的形式执行,多数用于回调函数
    sayHelloDlg dlg = new sayHelloDlg(sayHello);
    //委托链,可以通过+=和-=来进行多个委托赋值
    dlg += sayGoodBye;
    dlg -= sayHello;

    dlg("张三");
    Console.ReadKey();
}

除了提前写好方法,我们还可以用匿名函数

cs 复制代码
private static void Main(string[] args)
{
    //委托赋值的方法必须返回值和参数的格式一致
    //将方法以变量的形式传递,并且以方法的形式执行,多数用于回调函数
    sayHelloDlg dlg = new sayHelloDlg(sayHello);
    //委托链,可以通过+=和-=来进行多个委托赋值
    dlg += sayGoodBye;
    dlg -= sayHello;
    //匿名函数绑定,这里用的是=,所以前面的所有绑定的方法都清空,只保留这一个匿名函数了
    dlg = delegate (string name)
    {
        Console.WriteLine($"{name},我是匿名函数");
    };
    //用lamda表达式来帮写匿名函数
    dlg = (string name) =>
    {
        Console.WriteLine($"{name},我是lamda表达式");
    };
    dlg("张三");
    
    Console.ReadKey();
}

以上就是委托的使用

通过上面代码可以总结出,委托是一种类,引用类型的数据类型。它有返回值类型和参数列表,可以指向一个或多个方法。

当实例化委托后(即创建了一个委托的实例),这个委托类型的实例可以和任何其他方法关联起来,存储这些方法的引用,接着就可以通过委托类型的实例 间接调用这些存储的方法,通过委托我们可以将方法像引用类型一样传递,距离框架的回调函数,都可以通过委托实现

事件

接下来我们看看事件的使用

使用事件之前,还是要先声明个委托

事件是属于类的一个属性,不像委托那样可以声明在命名空间内,给事件赋值也可以使用+=和-=进行多个赋值

cs 复制代码
namespace ConsoleApp1
{
    //声明一个委托,无返回值带参数的
    public delegate void sayHelloDlg(string name);
    class Program
    {
        //声明一个事件
        public static event sayHelloDlg sayHelloEvent;

        private static void Main(string[] args)
        {

            sayHelloEvent += sayHelloPar;
            if (sayHelloEvent != null)
                sayHelloEvent("李四");
            
            Console.ReadKey();
        }
    }
}

通过代码我们可以理解为事件是委托的细分,委托范围大,事件可以将委托细分到分割分类里

委托和事件的区别

尽管事件和委托有许多共同点,但它们在概念上和使用上有一些区别。委托更多地被看作是一种引用方法的机制,而事件则是一种基于委托的通信机制,允许对象发布通知,其他对象可以订阅这些通知。

在实际应用中,事件通常用于实现发布-订阅模式,允许多个对象对同一事件作出响应,而委托则用于定义这些响应的方法。例如,在图形用户界面编程中,按钮点击可以是一个事件,而事件处理程序是一个委托,定义了当按钮被点击时应该执行的方法。

委托呢更是一种类型,比如参数传递,类型可以是委托但是不能是事件

事件呢他只能属于类,所以他比较安全,不会像委托那么广泛,更方便独立管理,避免类之外调用

概念和用途:

委托:委托是一种类型安全的引用,用于封装方法。它允许将方法作为参数传递给其他方法,或者存储和调用一组方法。委托允许类似于函数指针的功能,但在C#中更加类型安全和面向对象。

事件:事件是委托的一种特殊应用,用于实现发布-订阅模型。事件提供了一种通知机制,允许对象通知其他对象发生了特定的动作或状态改变。通过事件,一个对象(事件源)可以告知其他对象(事件订阅者)已经发生了某个行为或状态。

使用方式:

委托:委托可以直接通过实例化委托类型并调用其方法来使用,也可以通过 += 和 -= 运算符来添加和移除方法引用。

事件:事件(Event)本质上是委托(Delegate)的一种特殊用法。在C#中,事件通过声明一个委托类型的变量,然后使用 event 关键字来创建。这样做的目的是为了限制对委托调用列表的访问,只允许外部代码订阅(使用 +=)和取消订阅(使用 -=)事件,而不允许直接调用委托或修改调用列表。

安全性和封装:

委托:委托的调用列表可以被外部直接访问和修改,因此需要在使用时谨慎处理以确保类型安全和代码健壮性。

事件:事件封装了委托的调用过程,外部代码不能直接调用或修改事件的触发逻辑,只能通过提供的订阅和取消订阅方法来操作事件。

适用场景:

委托:适合在需要将方法作为参数传递或需要多播委托(即一个委托可以引用多个方法)的场景中使用。

事件:适合实现发布-订阅模式,特别是在GUI编程、多线程编程、异步编程等需要对象之间解耦的情况下。

相关推荐
Zer0_on43 分钟前
C++string类
开发语言·c++
Tomorrow'sThinker44 分钟前
25年1月更新。Windows 上搭建 Python 开发环境:Python + PyCharm 安装全攻略(文中有安装包不用官网下载)
开发语言·python·pycharm
禁默1 小时前
深入浅出:Java 抽象类与接口
java·开发语言
白宇横流学长2 小时前
基于Java的银行排号系统的设计与实现【源码+文档+部署讲解】
java·开发语言·数据库
勉灬之2 小时前
封装上传组件,提供各种校验、显示预览、排序等功能
开发语言·前端·javascript
西猫雷婶4 小时前
python学opencv|读取图像(二十三)使用cv2.putText()绘制文字
开发语言·python·opencv
我要学编程(ಥ_ಥ)5 小时前
速通前端篇——JavaScript
开发语言·前端·javascript
HEU_firejef6 小时前
设计模式——工厂模式
java·开发语言·设计模式
云计算DevOps-韩老师6 小时前
【网络云SRE运维开发】2024第52周-每日【2024/12/31】小测-计算机网络参考模型和通信协议的理论和实操考题
开发语言·网络·计算机网络·云计算·运维开发
fajianchen6 小时前
应用架构模式
java·开发语言