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中实现发布-订阅模式的核心语法糖;
  • 事件的多播能力本质上依赖委托的多播机制,二者底层逻辑一致,仅访问权限和使用场景有明确区分。
相关推荐
liulilittle6 小时前
XDP VNP虚拟以太网关(章节:一)
linux·服务器·开发语言·网络·c++·通信·xdp
我不是8神6 小时前
Qt 知识点全面总结
开发语言·qt
Ralph_Y6 小时前
多重继承与虚继承
开发语言·c++
今晚务必早点睡7 小时前
写一个Python接口:发送支付成功短信
开发语言·python
jghhh017 小时前
基于C#实现与三菱FX系列PLC串口通信
开发语言·算法·c#·信息与通信
ada7_7 小时前
LeetCode(python)22.括号生成
开发语言·数据结构·python·算法·leetcode·职场和发展
故事不长丨7 小时前
C#队列深度剖析:解锁高效编程的FIFO密码
visualstudio·c#·wpf·多线程·winfrom·队列·queue
喵了meme7 小时前
C语言实战练习
c语言·开发语言
imkaifan7 小时前
bind函数--修改this指向,返回一个函数
开发语言·前端·javascript·bind函数
love530love7 小时前
EPGF 新手教程 12在 PyCharm(中文版 GUI)中创建 Poetry 项目环境,并把 Poetry 做成“项目自包含”(工具本地化为必做环节)
开发语言·ide·人工智能·windows·python·pycharm·epgf