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中实现发布-订阅模式的核心语法糖;
  • 事件的多播能力本质上依赖委托的多播机制,二者底层逻辑一致,仅访问权限和使用场景有明确区分。
相关推荐
Keven_113 小时前
算法札记:ACM适用的很骚的C++语法(持续更新)
开发语言·c++
脉动数据行情14 小时前
C# 实现德指 DAX 期货 WebSocket 实时行情监听
开发语言·websocket·c#
码士集团小青4 小时前
C# 手写向量化能追上 C 吗?
c#
大圣编蚕4 小时前
Java ByteArrayInputStream 详解:从入门到实战
java·开发语言·算法
菜鸟~noob2334 小时前
【电子战】第02篇:能量检测器 vs. 相关检测器【含matlab代码】
开发语言·matlab
OpenAnolis小助手5 小时前
一句话看透 JVM,SysOM 诊断 Skill 新增 Java 应用诊断能力
java·开发语言·jvm·阿里云·操作系统控制台·sysom
小玮看世界5 小时前
[Python]OD算法在OD实际运用转化参考清单
开发语言·python·算法
ForteScarlet5 小时前
Kotlin 2.4.20 现已发布,新特性多不多?
android·java·开发语言·开源·kotlin·jetbrains
萧瑟余晖5 小时前
Java深入解析篇六十二之安全机制详解
java·开发语言
c#上位机6 小时前
tuple_max求数组中的最大值
c#·halcon·机器视觉