C# 一个完整的委托、事件学习示例

该示例符合委托、事件的定义规则,并且可以帮助大家更好地理解委托和事件的使用!

先定义了一个名为MyEventArgs的类,继承自EventArgs,它包含一个Message属性,用于存储传递的消息。Publisher类中添加了一个protected virtual的方法OnMyEvent,用于触发MyEvent事件,并传递MyEventArgs对象作为参数。在PublishMessage方法中,实例化了一个MyEventArgs对象,并通过调用OnMyEvent方法来触发事件。

Subscriber类中,修改了HandleEvent方法的签名,使其与MyDelegate委托类型匹配。当事件被触发时,通过MyEventArgs对象的Message属性获取传递的消息。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2
{
    internal class Program
    {

        // 定义事件数据类
        class MyEventArgs : EventArgs
        {
            public string Message { get; set; }
        }

        // 定义委托类型
        delegate void MyDelegate(object sender, MyEventArgs e);

        // 发布者类
        class Publisher
        {
            // 声明事件
            public event MyDelegate MyEvent;
             // 用于触发事件的保护方法
            protected virtual void OnMyEvent(MyEventArgs e)
            {
               
                MyEvent?.Invoke(this, e);
            }
               // 触发事件的方法
            public void PublishMessage(string message)
            {
                MyEventArgs args = new MyEventArgs { Message = message };
                OnMyEvent(args);
            }
        }

        // 订阅者类
        class Subscriber
        {
            public Subscriber(Publisher publisher)
            {
                // 订阅事件
                publisher.MyEvent += HandleEvent;
            }
                 // 事件处理方法
            private void HandleEvent(object sender, MyEventArgs e)
            {
                Console.WriteLine("Received message: " + e.Message);
            }
        }

        static void Main(string[] args)
        {
            // 创建发布者对象
            Publisher publisher = new Publisher();

            // 创建订阅者对象
            Subscriber subscriber = new Subscriber(publisher);

            // 发布消息
            publisher.PublishMessage("Hello World!");

            Console.ReadLine();
        }
    }

}

在这个程序中,有一个发布者类 Publisher 和一个订阅者类 Subscriber。发布者类定义了一个事件 MyEvent,并且有一个触发事件的方法 OnMyEvent。订阅者类在构造函数中订阅了发布者类的事件,并且定义了事件处理方法 HandleEvent

在 Main 方法中,创建了一个发布者对象 publisher 和一个订阅者对象 subscriber。然后通过调用 publisher 的 PublishMessage 方法发布一条消息。当消息发布时,订阅者会接收到消息并输出到控制台。

这个程序展示了事件和委托的典型用法,通过事件和委托可以实现对象之间的松耦合通信,使代码更加模块化和可扩展。

自定义事件参数类MyEventArgs

在 C# 中,事件通常由两个元素组成:事件本身和事件参数。事件参数类可能会包含一些属性,用于描述事件所携带的数据,以便在事件被触发时将这些数据传递给事件处理程序。MyEventArgs 是一个自定义的事件参数类,事件参数类会继承自 System.EventArgs 类,因 System.EventArgs 是 .NET Framework 中通用的事件参数基类。

在这个例子中,MyEventArgs 类包含一个名为 EventMessage 的属性,用于携带事件的消息信息。在触发 MyEvent 事件时,可以实例化一个 MyEventArgs 对象,并将它传递给事件处理程序,以便处理程序可以获取事件相关的信息。

 将OnMyEvent 与PublishMessage两个方法分开编写的好处在于代码的清晰性和可维护性。

OnMyEvent 方法,符合C#事件触发方法的命名规则(以 On 开头,后面跟上事件的名称),是用来触发事件的保护虚拟方法,通常用于在派生类中重写,以便在事件触发前进行一些额外的逻辑处理。这种设计模式符合了开闭原则,即对修改是封闭的,对扩展是开放的。将事件触发的逻辑封装在单独的方法中,使得在未来需要修改事件触发逻辑时可以在派生类中重写 OnMyEvent 方法,而无需修改 PublishMessage 方法。

PublishMessage 方法则是用于发布消息的公共方法,它创建事件参数并调用 OnMyEvent 方法来触发事件。这种分离的设计使得代码更易于理解和维护。

将这两句代码合并成一个方法可能会导致发布消息的逻辑与事件的触发逻辑紧密耦合在一起,增加了代码的复杂性和可维护性。因此,将它们分开写可以使代码更加清晰和易于理解。

 订阅事件放在构造函数里好呢,还是在执行代码中随时添加?

订阅事件应该根据具体的业务逻辑需求来决定是放在构造函数里还是在执行代码中随时添加。

如果订阅事件是作为对象的基本行为并且在整个对象的生命周期中都需要订阅,那么将订阅事件的代码放在构造函数中是一个合适的选择。这样可以确保在对象创建时就会订阅事件,而无需在每次使用对象时都手动添加订阅。

另一方面,如果订阅事件是根据特定的条件或者动态的情况来确定的,那么在执行代码中随时添加订阅可能会更合适。这样可以根据需要在适当的时候订阅事件,从而更灵活地管理事件订阅。

总的来说,根据具体的业务逻辑需求来决定订阅事件是放在构造函数还是在执行代码中随时添加,以确保代码结构清晰、易于理解和维护。

  • 53
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值