C#中Event事件的实现示例

 更新时间:2025年06月11日 09:33:16   作者:ghost143  
事件是委托的封装,用于解耦对象交互,支持多播通知,可传递参数,本文主要介绍了C#中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}");
    }
}

以上内容涵盖了如何定义、使用和扩展事件。更多相关C# Event事件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#如何连接服务器共享文件夹

    C#如何连接服务器共享文件夹

    这篇文章主要为大家详细介绍了C#如何连接服务器共享文件夹,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • 带着问题读CLR via C#(笔记二)类型基础

    带着问题读CLR via C#(笔记二)类型基础

    A1: Object类型共包含6个方法,Equals, GetHashCode, ToString, GetType, MemberwiseClone和Finalize.
    2013-04-04
  • WPF实现炫酷的界面交互效果的代码详解

    WPF实现炫酷的界面交互效果的代码详解

    在当今竞争激烈的软件市场中,用户界面的交互体验至关重要,一个拥有炫酷动画特效的应用程序,不仅能吸引用户的注意力,还能显著提升用户与界面的交互流畅度和愉悦感,本文将深入剖析WPF动画特效的各个方面,通过大量详细的代码示例和对关键概念的深入解释
    2025-02-02
  • 配置C#的系统环境变量的方法

    配置C#的系统环境变量的方法

    配置C#的系统环境变量的方法...
    2007-03-03
  • C#利用TreeView控件实现目录跳转

    C#利用TreeView控件实现目录跳转

    这篇文章主要为大家详细介绍了C#润滑利用TreeView控件实现目录跳转功能,文中的示例代码讲解详细,感兴趣的小伙伴可以动手尝试一下
    2022-07-07
  • c# WPF中通过双击编辑DataGrid中Cell的示例(附源码)

    c# WPF中通过双击编辑DataGrid中Cell的示例(附源码)

    这篇文章主要介绍了c# WPF中通过双击编辑DataGrid中Cell的示例(附源码),帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-03-03
  • c# for循环中创建线程执行问题

    c# for循环中创建线程执行问题

    这篇文章主要介绍了有关c# for循环中创建线程执行问题,下面文章将将以举例的方式展开for循环中创建线程执行问题的内容,需要的朋友可以参考一下,希望对你有所帮助
    2021-11-11
  • Unity多语言转换工具的实现

    Unity多语言转换工具的实现

    这篇文章主要为大家详细介绍了Unity多语言转换工具的实现,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-06-06
  • C#生成Code39条形码而非条形码字体的方法

    C#生成Code39条形码而非条形码字体的方法

    由于Code39编译简单、能够对任意长度的数据进行编码、支持设备比较广泛所以被广泛的采用,下面介绍下C#生成Code39条形码而非条形码字体的方法,需要的朋友可以参考下
    2015-07-07
  • Unity Shader相交算法实现简易防能量盾

    Unity Shader相交算法实现简易防能量盾

    这篇文章主要为大家详细介绍了Unity Shader相交算法实现简易防能量盾,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04

最新评论