一篇文章彻底搞清楚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日

相关文章

  • layui实现显示数据表格、搜索和修改功能示例

    以下是将layui用于显示数据表格、搜索和修改功能的完整攻略。 前置条件 首先你需要安装layui包,你可以从layui官网下载或使用CDN链接 引入layui.js和layui.css文件 显示数据表格 这是一个基于layui table模块的示例。下面是一个基本的HTML结构,它定义了一个table和一个div包含分页: <table id=&qu…

    C# 2023年5月31日
    00
  • C#利用win32 Api 修改本地系统时间、获取硬盘序列号

    修改本地系统时间 首先需要导入System.Runtime.InteropServices这个命名空间. using System.Runtime.InteropServices; 然后我们通过GetSystemTime方法获取系统时间,再通过SetSystemTime方法修改系统时间. [DllImport("Kernel32.dll"…

    C# 2023年6月1日
    00
  • 深入了解c# 信号量和互斥体

    深入了解C# 信号量和互斥体 信号量(Semaphore) 信号量是一种线程同步工具,它可以在多个线程之间控制对资源的访问。Semaphore(信号量)在C#中,可以通过Semaphore类来实现。 基本概念 Semaphore可以理解为一个计数器,用于记录可同时访问某个资源的线程数量。假设信号量的值为n,那么前n个线程可以同时访问资源,第n+1个线程需要等…

    C# 2023年6月7日
    00
  • c# for循环中创建线程执行问题

    创建线程是C#中一种常见且重要的操作,而在循环中创建线程又是一种比较常见的需求。本文将就“C#中循环中创建线程执行问题”给出具体的攻略。 1. 为什么要在循环中创建线程 在一些情况下,我们有需要对一堆数据进行处理,每个数据的处理方式是一样的。那么我们就可以使用循环来实现遍历,把每个数据都处理一遍。这样做有时候会比单个单个处理要更方便和高效。 然而,这些任务可…

    C# 2023年5月15日
    00
  • Asp.net core前端框架Blazor介绍

    Blazor 是一个使用 C# 和 Razor 语法构建现代 Web 应用程序的开源框架。它允许开发人员使用 C# 语言编写客户端代码,而无需使用 JavaScript。以下是 Asp.net core 前端框架 Blazor 的详细介绍: Blazor 的工作原理 Blazor 的工作原理是将 C# 代码编译成 WebAssembly,然后在浏览器中运行。…

    C# 2023年5月17日
    00
  • 基于C#制作一个休息提醒闹钟的详细步骤

    下面我将介绍基于C#制作一个休息提醒闹钟的详细步骤。 步骤一:新建WPF应用程序 从Visual Studio的开始菜单或欢迎屏幕中,选择新建项目(或点击Ctrl + Shift + N)。 选择WPF应用程序模板,并选择合适的项目名称和位置。然后点击“创建”按钮。 步骤二:设计用户界面 在设计用户界面方面,可参考以下示例: <Window x:Cla…

    C# 2023年5月15日
    00
  • C#使用对象序列化类库MessasgePack

    下面就为您详细讲解一下 C# 使用对象序列化类库 MessasgePack 的完整攻略。 MessagePack 简介 MessagePack 是一种高效的二进制序列化格式,它比 JSON、XML 等其他格式更节省存储空间、更快的数据序列化和反序列化速度。它具有跨语言、轻量级、易于使用、可扩展等特点,广泛应用于 Web 应用、移动应用、游戏开发等领域。 为什…

    C# 2023年5月31日
    00
  • C#中的除法运算符与VB.NET中的除法运算符

    好的。针对“C#中的除法运算符与VB.NET中的除法运算符”,我会就这个话题,进行详细讲解,以下是完整的攻略: C#中的除法运算符 / C#中的除法运算符 / 是将两个数相除并返回结果的算术运算符。如果两个操作数都是整数,则返回的结果也是整数,省略小数部分。如果其中一个操作数是浮点数,则返回的结果也是浮点数,包括小数部分。下面是一个简单的示例: int a …

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