一篇文章彻底搞清楚c#中的委托与事件

一篇文章彻底搞清楚C#中的委托与事件

委托

委托(Delegate)是一种类型,它可以持有函数的引用并执行这个函数。通过委托,我们可以在不知道函数名的情况下,直接访问和执行函数。

定义

在C#中,委托是定义在类的外部,但是要在类的内部定义具体的委托实例。委托的定义格式如下:

public delegate void DelegateName(parameters)

其中 DelegateName 就是委托的名称,而 parameters 是委托所需要的参数。

委托的使用

定义

首先,我们需要定义一个委托类型:

public delegate int MyDelegate(int a, int b);

这个委托类型可以被用来表示一个带有两个 int 类型参数并且返回值也为 int 类型的方法。

实例化

然后,我们可以通过委托类型实例化一个委托,这个委托将会执行一个方法。

public class DelegateExample
{
    public static int Add(int a, int b)
    {
        return a + b;
    }

    public static void Main()
    {
        // 实例化一个委托
        MyDelegate myDelegate = new MyDelegate(Add);

        // 使用委托执行 Add 方法
        int result = myDelegate(1, 2);
        Console.WriteLine("1 + 2 = " + result);
    }
}

在这个例子中,我们实例化了一个 MyDelegate 委托,然后通过 myDelegate 来调用 Add 方法。

委托链

委托链是一种将多个委托实例组合在一起并依次执行的方式。

添加委托

我们可以通过 += 操作符向委托链中添加委托:

public class DelegateExample
{
    public static int Add(int a, int b)
    {
        return a + b;
    }

    public static int Multiply(int a, int b)
    {
        return a * b;
    }

    public static void Main()
    {
        // 实例化两个委托
        MyDelegate addDelegate = new MyDelegate(Add);
        MyDelegate multiplyDelegate = new MyDelegate(Multiply);

        // 将委托实例添加到委托链中
        MyDelegate myDelegate = addDelegate;
        myDelegate += multiplyDelegate;

        // 依次执行委托链中的委托
        int result = myDelegate(1, 2);
        Console.WriteLine("1 + 2 * 2 = " + result);
    }
}

在这个例子中,我们定义了两个带有两个 int 类型参数并且返回值也为 int 类型的方法,然后实例化了两个 MyDelegate 类型的委托。接着我们将这两个委托实例添加到了委托链中,并依次执行了这个委托链。

移除委托

我们可以通过 -= 操作符从委托链中移除委托:

public class DelegateExample
{
    public static int Add(int a, int b)
    {
        return a + b;
    }

    public static int Multiply(int a, int b)
    {
        return a * b;
    }

    public static void Main()
    {
        // 实例化两个委托
        MyDelegate addDelegate = new MyDelegate(Add);
        MyDelegate multiplyDelegate = new MyDelegate(Multiply);

        // 将委托实例添加到委托链中
        MyDelegate myDelegate = addDelegate;
        myDelegate += multiplyDelegate;

        // 从委托链中移除委托实例
        myDelegate -= addDelegate;

        // 依次执行委托链中的委托
        int result = myDelegate(1, 2);
        Console.WriteLine("1 * 2 = " + result);
    }
}

在这个例子中,我们使用了 -= 操作符将 addDelegate 委托从委托链中移除,然后只剩下了 multiplyDelegate 委托实例。

事件

事件(Event)是一种特殊的委托,它可以在委托链中添加和移除委托实例。当事件被触发时,委托链中所有的委托实例都会被执行。

定义

在C#中,事件的定义格式如下:

public event EventHandler EventName;

其中 EventHandler 是一个预定义的委托类型,用于处理事件。

定义自定义事件处理程序

public class CustomEventArgs : EventArgs
{
    public CustomEventArgs(string s)
    {
        Message = s;
    }

    public string Message { get; set; }
}

public class EventExample
{
    public delegate void CustomEventHandler(object sender, CustomEventArgs args);

    public event CustomEventHandler CustomEvent;

    public void RaiseEvent(string message)
    {
        OnCustomEvent(new CustomEventArgs(message));
    }

    protected virtual void OnCustomEvent(CustomEventArgs e)
    {
        CustomEvent?.Invoke(this, e);
    }
}

在这个例子中,我们定义了一个 CustomEventArgs 类型,用于包含我们需要传递至事件处理程序的自定义参数。然后我们定义了一个 CustomEventHandler 委托,用于处理事件。随后我们定义了一个 CustomEvent 事件,并在 RaiseEvent 方法中触发这个事件。

由于事件只能触发委托链中的方法,因此我们需要在事件定义中使用一个委托类型,而不是使用一个具体的处理程序。然后,在 OnCustomEvent 方法中,我们调用了委托链中所有的委托实例。

注册事件

public void RegisterEvent(EventExample ex)
{
    ex.CustomEvent += CustomEventHandler1;
    ex.CustomEvent += CustomEventHandler2;
}

public void CustomEventHandler1(object sender, CustomEventArgs args)
{
    Console.WriteLine(args.Message + " from EventHandler1.");
}

public void CustomEventHandler2(object sender, CustomEventArgs args)
{
    Console.WriteLine(args.Message + " from EventHandler2.");
}

在这个例子中,我们向 EventExample 中的 CustomEvent 事件注册两个事件处理程序。当事件被触发时,CustomEventHandler1CustomEventHandler2 会被依次执行。

触发事件

public void TriggerEvent(EventExample ex)
{
    ex.RaiseEvent("This is a custom event.");
}

在这个例子中,我们通过调用 RaiseEvent 方法来触发 CustomEvent 事件。这个方法将会依次执行 CustomEventHandler1CustomEventHandler2

总结

  • 委托是一种可以持有函数引用并执行这个函数的类型。通过委托,我们可以在不知道函数名的情况下,访问和执行这个函数。
  • 委托链是一种将多个委托实例组合在一起并依次执行的方式。
  • 事件是一种特殊的委托,可以在委托链中添加和移除委托实例。当事件被触发时,委托链中所有的委托实例都会被执行。

示例

下面是一个简单的示例,演示了如何使用委托和事件:

using System;

public delegate int MyDelegate(int a, int b);

public class DelegateExample
{
    public static int Add(int a, int b)
    {
        return a + b;
    }

    public static int Multiply(int a, int b)
    {
        return a * b;
    }

    public static void Main()
    {
        // 实例化两个委托
        MyDelegate addDelegate = new MyDelegate(Add);
        MyDelegate multiplyDelegate = new MyDelegate(Multiply);

        // 将委托实例添加到委托链中
        MyDelegate myDelegate = addDelegate;
        myDelegate += multiplyDelegate;

        // 依次执行委托链中的委托
        int result = myDelegate(1, 2);
        Console.WriteLine("1 + 2 * 2 = " + result);

        // 定义事件
        EventExample ex = new EventExample();

        // 注册事件
        RegisterEvent(ex);

        // 触发事件
        TriggerEvent(ex);
    }

    public static void RegisterEvent(EventExample ex)
    {
        ex.CustomEvent += CustomEventHandler1;
        ex.CustomEvent += CustomEventHandler2;
    }

    public static void CustomEventHandler1(object sender, CustomEventArgs args)
    {
        Console.WriteLine(args.Message + " from EventHandler1.");
    }

    public static void CustomEventHandler2(object sender, CustomEventArgs args)
    {
        Console.WriteLine(args.Message + " from EventHandler2.");
    }

    public static void TriggerEvent(EventExample ex)
    {
        ex.RaiseEvent("This is a custom event.");
    }
}

public class CustomEventArgs : EventArgs
{
    public CustomEventArgs(string s)
    {
        Message = s;
    }

    public string Message { get; set; }
}

public class EventExample
{
    public delegate void CustomEventHandler(object sender, CustomEventArgs args);

    public event CustomEventHandler CustomEvent;

    public void RaiseEvent(string message)
    {
        OnCustomEvent(new CustomEventArgs(message));
    }

    protected virtual void OnCustomEvent(CustomEventArgs e)
    {
        CustomEvent?.Invoke(this, e);
    }
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:一篇文章彻底搞清楚c#中的委托与事件 - Python技术站

(0)
上一篇 2023年6月7日
下一篇 2023年6月7日

相关文章

  • C# Random类随机函数实例详解

    C# Random类随机函数实例详解 在C#编程中,经常需要使用到随机数,C#中提供了Random类,可以非常方便地生成伪随机数。本文将针对C# Random类进行详细讲解,并附上两个示例说明。 1. Random类概述 Random类可以生成一个伪随机数序列。 随机数是一些不可预测的数字,它们是通过算法生成的,而不是通过任何物理过程生成的。 随机类的构造函…

    C# 2023年6月8日
    00
  • 详解C# 代码占用的空间

    下面是详解C#代码占用空间的攻略。 标题 首先,我们需要知道C#代码占用空间的主要原因是由于引用程序集、变量及方法等所占用的内存空间。 代码引用的程序集 在C#开发过程中,使用一些第三方库或者自己写的库是很常见的。这些库在使用时需要在代码中进行引用,而引用过程中会占用一定的内存空间。 例如,下面的代码中使用了NLog库来进行日志记录: using NLog;…

    C# 2023年5月31日
    00
  • asp.net C#实现解压缩文件的方法

    实现解压缩文件的方法可以使用C#中的System.IO.Compression命名空间中的ZipFile类。我们可以使用ZipFile类中提供的方法对zip文件进行解压缩。下面是详细的步骤: 步骤一:导入命名空间 使用前需要导入System.IO.Compression命名空间,使用以下代码: using System.IO.Compression; 步骤二…

    C# 2023年6月1日
    00
  • C#打印PDF文档的10种方法(小结)

    下面我将为您详细讲解“C#打印PDF文档的10种方法(小结)”的完整攻略。 1. 概述 在C#中打印PDF文档可以用多种方法,本文将介绍10种常用的方法,并举例说明,帮助开发者更好的理解。 2. iTextSharp库 iTextSharp是一个流行的开源PDF开发库,可以用C#和VB.NET编写PDF文件。它不仅可以创建PDF文件,还可以读取、编辑、添加注…

    C# 2023年6月1日
    00
  • C#实现String类型和json之间的相互转换功能示例

    C#实现String类型和JSON之间的相互转换功能示例 1. 前言 在现代Web开发中,常常需要将服务器数据以JSON(JavaScript Object Notation)格式传输到客户端,或者将客户端数据以JSON格式上传到服务器。同时,C#作为一门强类型的编程语言,当我们需要将JSON格式的字符串转换为C#的String类型或者反之,就需要使用到相互…

    C# 2023年5月31日
    00
  • go micro微服务proto开发安装及使用规则

    下面我将详细讲解 “go micro微服务proto开发安装及使用规则” 的完整攻略。 什么是 go micro go-micro 是一套微服务框架,使用 Go 编程语言实现,简化了构建复杂分布式系统的过程。它封装了服务注册与发现、负载均衡、消息传递、服务治理、数据传输等基本功能,让开发人员可以更加专注于业务逻辑的实现。此外,go-micro 还支持多种协议…

    C# 2023年5月15日
    00
  • jquery实现pager控件示例

    jQuery是一个流行的JavaScript库,它可以帮助开发人员更轻松地操作HTML文档、处理事件和执行动画等。本文将介绍如何使用jQuery实现一个分页控件,以便在Web应用程序中显示大量数据。 实现分页控件 以下是使用jQuery实现分页控件的步骤: 步骤1:创建HTML结构 首先,我们需要创建一个HTML结构来显示分页控件。以下是一个基本的HTML结…

    C# 2023年5月15日
    00
  • c#集合快速排序类实现代码分享

    下面我将详细讲解如何使用C#集合快速排序类实现代码。 标题 1. 什么是快速排序? 快速排序是最常用的排序算法之一,其基本思想是将一个数组分成两个子数组,然后对这两个子数组分别进行排序,最终将整个数组排序完成。 2. C#集合快速排序类 在C#中,集合快速排序类可以用来对集合进行排序。它在System.Collections.Generic命名空间中定义,可…

    C# 2023年5月31日
    00
合作推广
合作推广
分享本页
返回顶部