C#委托和事件的区别

委托

复制代码
  可以理解为函数的指针

代码示例:

csharp 复制代码
  class Program
    {
        //定义委托
        public delegate void StudyDelegate(string name);

        //定义方法
        public static void Math(string name)
        {

            Console.WriteLine(name + "学习数学");
        }

        public static void English(string name)
        {

            Console.WriteLine(name + "学习英文");
        }
        static void Main(string[] args)
        {
            //委托绑定方法
            StudyDelegate studyDelegate = Math;
            //委托绑定多个方法
            studyDelegate += English;
            //掉用委托
            studyDelegate.Invoke("小明");


            //通过内置Action方法实现委托
            Action<string> studyDelegate2 = Math;
            studyDelegate2 += English;
            studyDelegate.Invoke("小明");
            Console.ReadKey();
        }

    }

public delegate void StudyDelegate(string name); 通过关键字delegate声明是委托对象
通过+=,-= ,对委托对象实现方法的绑定和方法的移除
Action< T >, Func<T,TResult>,内置方法,实现委托,Action无返回值,Func有返回值

事件

复制代码
特殊的委托机制,将委托的访问权限限制起来,开发者只需要通过+=,-=进行方法的订阅和取消订阅

代码示例:

csharp 复制代码
 class Program
    {
        //定义委托
        public delegate void StudyDelegate(string name);

        public static event StudyDelegate StudyEvent;

        public static void Study(string name)
        {

            StudyEvent?.Invoke(name);
        }

        //定义方法
        public static void Math(string name)
        {

            Console.WriteLine(name + "学习数学");
        }

        public static void English(string name)
        {

            Console.WriteLine(name + "学习英文");
        }
        static void Main(string[] args)
        {
            StudyEvent += Math;
            StudyEvent += English;
            Study("小明");

        }

    }

一版情况下,委托的对象会包含sender,eventArg等,代表穿过来的对象,对象参数等,类似winform中控件的事件。如下代码示例:

csharp 复制代码
class Program
    {

        static void Main(string[] args)
        {
            Publish publish = new Publish();

            //无数据传输事件
            publish.publishHandler += (sendr, e) =>
            {
                Console.WriteLine("事件绑定方法1");
            };
            publish.Raise();

            //数据传输事件
            publish.publishHandler_cus += (sendr, e) => { Console.WriteLine("参数msg:" + e.msg); };
            publish.Raise_cus("自定义参数");


            Console.ReadKey();



        }

    }


    //自定义传入参数
    public class CUSEventArgs : EventArgs
    {

        public string msg { get; set; }

    }


    //事件类型
    public class Publish
    {
        public event EventHandler publishHandler;

        public void Raise()
        {

            publishHandler.Invoke(this, null);
        }

        public event EventHandler<CUSEventArgs> publishHandler_cus;

        public void Raise_cus(string message)
        {

            publishHandler_cus.Invoke(this, new CUSEventArgs { msg = message });
        }


    }

EventHandler为内置的事件委托,此默认是包含sender和EventArgs,通过泛型可以修改EventArgs的类型,上面例子是通过CUSEventArgs 继承添加了msg参数。

两者区别

特性 委托(Delegate) 事件(Event)
访问权限 外部可直接调用、覆盖 外部仅能订阅 / 取消订阅
本质 引用类型(函数指针) 委托的封装(特殊语法)
适用场景 灵活的方法封装、回调 发布 - 订阅模式、解耦组件
多播支持 支持(+=/-=) 支持(底层依赖委托多播)

补充说明

  • 委托的"直接调用"特性使其灵活性更高,但缺乏访问管控,外部代码可随意调用或覆盖委托指向的方法;
  • 事件是委托的封装形式,仅对外暴露订阅(+=)和取消订阅(-=)操作,避免了委托被外部滥用,是.NET中实现发布-订阅模式的核心语法糖;
  • 事件的多播能力本质上依赖委托的多播机制,二者底层逻辑一致,仅访问权限和使用场景有明确区分。
相关推荐
为何创造硅基生物6 小时前
C语言 结构体内存对齐规则(通俗易懂版)
c语言·开发语言
吃好睡好便好6 小时前
在Matlab中绘制横直方图
开发语言·学习·算法·matlab
星寂樱易李6 小时前
iperf3 + Python-- 网络带宽、网速、网络稳定性
开发语言·网络·python
仰泳之鹅6 小时前
【C语言】自定义数据类型2——联合体与枚举
c语言·开发语言·算法
之歆7 小时前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
cen__y8 小时前
Linux12(Git01)
linux·运维·服务器·c语言·开发语言·git
AI人工智能+电脑小能手8 小时前
【大白话说Java面试题 第65题】【JVM篇】第25题:谈谈对 OOM 的认识
java·开发语言·jvm
社交怪人8 小时前
【算平均分】信息学奥赛一本通C语言解法(题号2071)
c语言·开发语言
郭涤生9 小时前
不同主机之间网络通信-以太网连接复习
开发语言·rk3588
山居秋暝LS9 小时前
【无标题】RTX00安装paddle OCR,win11不能装最新的,也不能用GPU
开发语言·r语言