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 分钟前
Spark.NET:一个试图把 Django / Rails 式开发体验带回 .NET 世界的全栈 Web 框架。
c#
AIFarmer12 分钟前
【无标题】
开发语言·c++·算法
昇腾CANN26 分钟前
TileLang-Ascend 算子性能优化方法与实操
开发语言·javascript·性能优化·昇腾·cann
沐知全栈开发37 分钟前
ionic 手势事件详解
开发语言
lsx2024061 小时前
Bootstrap 按钮
开发语言
神仙别闹1 小时前
基于 Python 实现 BERT 的情感分析模型
开发语言·python·bert
禾叙_1 小时前
【langchain4j】结构化输出(六)
java·开发语言
NQBJT1 小时前
VS Code配置Python人工智能开发环境
开发语言·人工智能·vscode·python
byoass1 小时前
智巢AI知识库深度解析:企业文档管理从大海捞针到精准狙击的进化之路
开发语言·网络·人工智能·安全·c#·云计算
南境十里·墨染春水1 小时前
C++笔记 STL——set
开发语言·c++·笔记