C#学习第14天:Event事件

什么是事件?


定义

  • 事件是一种特殊的委托,用于在某一动作发生时通知其他对象。
  • 它允许一个对象向多个监听者广播消息。

用途

  • 实现发布-订阅模式,主要用于解耦对象之间的交互,不同模块能动态响应特定事件。

和委托关系 

  • 委托是事件的基础,它定义了事件处理器的签名。事件是基于委托的封装和扩展。

事件的组成部分

  • 事件声明:在类中定义事件,通常使用event关键字。
  • 事件触发:在某个动作完成后,引发事件。
  • 事件订阅:外部对象注册方法来响应事件。 

基本语法


1. 定义事件

public delegate void NotifyEventHandler(object sender, EventArgs e);

public class Process
{
    // 使用委托类型定义事件
    public event NotifyEventHandler ProcessCompleted;

    public void StartProcess()
    {
        Console.WriteLine("Process started.");
        
        // 模拟过程完成后引发事件
        OnProcessCompleted(EventArgs.Empty);
    }

    protected virtual void OnProcessCompleted(EventArgs e)
    {
        ProcessCompleted?.Invoke(this, e);
    }
}

2. 订阅和触发事件 

public class Program
{
    public static void Main()
    {
        Process process = new Process();
        
        // 订阅事件
        process.ProcessCompleted += Process_ProcessCompleted;
        
        process.StartProcess();
    }

    private static void Process_ProcessCompleted(object sender, EventArgs e)
    {
        Console.WriteLine("Process completed event received.");
    }
}

说明:

  • ProcessCompleted事件是在OnProcessCompleted方法中触发的。
  • Process_ProcessCompleted是事件处理器,当事件被触发时会被调用。 

高级主题 


内置事件处理器

  • EventHandler:这是C#提供的标准事件处理器委托类型,常用于无数据或简单数据的事件:
public event EventHandler ProcessCompleted;
  •  EventHandler<TEventArgs>:用于传递附加信息:
public class CustomEventArgs : EventArgs
{
    public string Message { get; set; }
}

public event EventHandler<CustomEventArgs> ProcessCompletedWithMessage;

 使用内置EventHandler

public class SimpleProcess
{
    public event EventHandler ProcessCompleted;

    public void CompleteProcess()
    {
        Console.WriteLine("Completing process...");
        ProcessCompleted?.Invoke(this, EventArgs.Empty);
    }
}

自定义事件参数

  • 如果需要传递额外的数据,可以创建自定义的事件参数类。
public class DownloadEventArgs : EventArgs
{
    public string FileName { get; set; }
    public long FileSize { get; set; }
}

public class DownloadManager
{
    public event EventHandler<DownloadEventArgs> DownloadCompleted;

    public void CompleteDownload(string fileName, long fileSize)
    {
        Console.WriteLine($"Download completed: {fileName}, Size: {fileSize}");
        OnDownloadCompleted(new DownloadEventArgs { FileName = fileName, FileSize = fileSize });
    }

    protected virtual void OnDownloadCompleted(DownloadEventArgs e)
    {
        DownloadCompleted?.Invoke(this, e);
    }
}

 事件的多播特性

事件是基于委托的,因此支持多播,即多个订阅者可以同时接收同一事件通知。

public static void HandleSuccess(object sender, EventArgs e)
{
    Console.WriteLine("Success handler executed.");
}

public static void Main()
{
    SimpleProcess sp = new SimpleProcess();
    
    // 多个方法订阅同一事件
    sp.ProcessCompleted += Process_ProcessCompleted;
    sp.ProcessCompleted += HandleSuccess;
    
    sp.CompleteProcess();
}

实践习题


1.创建一个类DownloadManager,定义一个DownloadCompleted事件。在下载完成后触发此事件,并在主程序中订阅和处理该事件。

using System;

public class DownloadManager
{
    public event EventHandler DownloadCompleted;

    public void StartDownload()
    {
        Console.WriteLine("Starting download...");

        // Simulate download completion
        OnDownloadCompleted(EventArgs.Empty);
    }

    protected virtual void OnDownloadCompleted(EventArgs e)
    {
        DownloadCompleted?.Invoke(this, e);
    }
}

public class Program
{
    public static void Main()
    {
        DownloadManager dm = new DownloadManager();
        
        // 订阅事件
        dm.DownloadCompleted += Download_Completed;
        
        dm.StartDownload();
    }

    private static void Download_Completed(object sender, EventArgs e)
    {
        Console.WriteLine("Download completed event received.");
    }
}

2.修改上述DownloadManager,使得DownloadCompleted事件携带下载的文件名和大小信息。

using System;

public class DownloadEventArgs : EventArgs
{
    public string FileName { get; set; }
    public long FileSize { get; set; }
}

public class DownloadManager
{
    public event EventHandler<DownloadEventArgs> DownloadCompleted;

    public void StartDownload(string fileName, long fileSize)
    {
        Console.WriteLine($"Starting download of {fileName}...");

        // Simulate download completion
        OnDownloadCompleted(new DownloadEventArgs { FileName = fileName, FileSize = fileSize });
    }

    protected virtual void OnDownloadCompleted(DownloadEventArgs e)
    {
        DownloadCompleted?.Invoke(this, e);
    }
}

public class Program
{
    public static void Main()
    {
        DownloadManager dm = new DownloadManager();
        
        // 订阅事件
        dm.DownloadCompleted += Download_Completed;
        
        dm.StartDownload("example.txt", 1024);
    }

    private static void Download_Completed(object sender, DownloadEventArgs e)
    {
        Console.WriteLine($"Download completed: {e.FileName}, Size: {e.FileSize}");
    }
}

以上内容涵盖了如何定义、使用和扩展事件。掌握这些知识能够有效地编写模块化、解耦的代码。如果有其他问题或需要进一步讲解,请随时告诉我!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ghost143

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值