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中实现发布-订阅模式的核心语法糖;
  • 事件的多播能力本质上依赖委托的多播机制,二者底层逻辑一致,仅访问权限和使用场景有明确区分。
相关推荐
码农水水2 分钟前
米哈游Java面试被问:Shenandoah GC的Brooks Pointer实现机制
java·开发语言·jvm·spring boot·redis·安全·面试
小程同学>o<4 分钟前
嵌入式之C/C++(二)内存
c语言·开发语言·c++·笔记·嵌入式软件·面试题库
程序员清洒7 分钟前
Flutter for OpenHarmony:Dialog 与 BottomSheet — 弹出式交互
开发语言·flutter·华为·交互·鸿蒙
cyforkk8 分钟前
07、Java 基础硬核复习:面向对象编程(进阶)的核心逻辑与面试考点
java·开发语言·面试
钱多多先森17 分钟前
【Dify】使用 python 调用 Dify 的 API 服务,查看“知识检索”返回内容,用于前端溯源展示
开发语言·前端·python·dify
qq_4171292517 分钟前
基于C++的区块链实现
开发语言·c++·算法
霍理迪18 分钟前
JS—数组
开发语言·前端·javascript
Ulyanov19 分钟前
超越平面:用impress.js打造智能多面棱柱演示器
开发语言·前端·javascript·平面
2401_8324027520 分钟前
C++中的命令模式实战
开发语言·c++·算法
zhougl99621 分钟前
Java定时任务实现
java·开发语言·python