c#委托与事件(详解)

C#委托与事件(详解)

什么是委托?

在C#中,委托是一个类,用于指向和调用一个或多个方法。可以将委托看做是方法的类型。通过委托,我们可以在运行时确定要调用哪个方法,而无需提前确定调用哪个方法。

如何定义委托?

在C#中,委托的定义非常简单,只需使用delegate关键字即可。

delegate 返回类型 委托名称(参数列表);

其中,

  • 返回类型:委托指向方法的返回值类型;
  • 委托名称:定义的委托名称;
  • 参数列表:委托指向方法的参数列表。

委托名称可以自定义,建议名称要见名知意。例如,要定义一个委托来作为一个方法的回调函数,可以这样写:

delegate void Callback(string arg1, int arg2);

如何使用委托?

定义了一个委托之后,就可以使用它来指向方法了。委托指向方法的语法为:

委托名称 变量名称 = new 委托名称(方法名);

其中,

  • 委托名称:先前定义的委托名称;
  • 变量名称:委托变量的名称;
  • 方法名:要指向的方法的名称。

例如,要使用上文定义的Callback委托来指向一个名为DoSomething的方法,可以这样写:

Callback callback = new Callback(DoSomething);

在这个例子中,DoSomething方法的定义如下:

void DoSomething(string arg1, int arg2)
{
    Console.WriteLine("DoSomething called! arg1 = {0}, arg2 = {1}", arg1, arg2);
}

然后,我们可以使用callback委托变量来调用DoSomething方法,如下所示:

callback("hello", 123);

什么是事件?

在C#中,事件是一种特殊的委托,它代表了一组在对象上发生的动作或操作。当事件在对象上触发时,订阅者(或观察者)将收到通知,并有机会执行相应的动作或操作。

如何定义事件?

在C#中,事件的定义遵循以下模式:

public event 委托名称 事件名称;

其中,

  • public:事件的访问修饰符,用于控制事件的可见性;
  • event:事件关键字;
  • 委托名称:前面定义的委托名称,用于指定事件的处理程序类型;
  • 事件名称:事件的名称。

例如,要定义一个事件来处理一个名为EventName的事件,可以这样写:

public event EventHandler EventName;

在这个例子中,使用了C#内置的EventHandler委托类型,它具有以下签名:

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

在事件发生时,触发事件的对象会将自己作为sender参数传递给事件处理程序,同时生成一个EventArgs实例作为e参数传递给事件处理程序。

如何订阅事件?

订阅事件是指将一个或多个方法注册为事件处理程序,以便在事件发生时能够接收通知并执行相应的操作。

在C#中,可以使用以下语法来订阅事件:

对象实例.事件名称 += 事件处理程序方法;

其中,

  • 对象实例:触发事件的对象实例;
  • 事件名称:要订阅的事件名称;
  • 事件处理程序方法:一个能够响应事件的方法。

例如,要订阅上文定义的EventName事件,可以这样写:

obj.EventName += new EventHandler(EventHandlerMethod);

在这个例子中,EventHandlerMethod是一个能够响应EventName事件的方法,定义如下:

void EventHandlerMethod(object sender, EventArgs e)
{
    Console.WriteLine("Event has occurred!");
}

EventName事件发生时,EventHandlerMethod方法将被调用。

如何触发事件?

在C#中,可以使用以下语法来触发事件:

事件名称?.Invoke(发送事件的对象, EventArgs实例);

其中,

  • 事件名称:要触发的事件名称;
  • 发送事件的对象:触发事件的对象实例;
  • EventArgs实例:事件参数。

例如,要触发上文定义的EventName事件,可以这样写:

EventName?.Invoke(this, EventArgs.Empty);

this表示当前对象实例,EventArgs.Empty表示没有任何事件数据。

示例1:使用委托实现函数指针

在这个示例中,我们将演示如何使用委托来实现函数指针。

using System;

namespace Demo1
{
    delegate void Callback();

    class Program
    {
        static void Main(string[] args)
        {
            Callback callback = new Callback(SayHello);
            callback();
        }

        static void SayHello()
        {
            Console.WriteLine("Hello World!");
        }
    }
}

在这个示例中,我们定义了一个Callback委托类型,它能够指向没有参数、没有返回值的方法。然后,我们创建了一个callback委托变量,并将它指向一个名为SayHello的方法。最后,我们使用callback委托变量来调用SayHello方法。

示例2:使用事件处理程序

在这个示例中,我们将演示如何使用事件处理程序在不同对象之间通信。

using System;

namespace Demo2
{
    public class Button
    {
        public event EventHandler Click;

        public void OnClick()
        {
            Click?.Invoke(this, EventArgs.Empty);
        }
    }

    public class MainForm
    {
        private Button button;

        public MainForm()
        {
            button = new Button();
            button.Click += new EventHandler(ButtonClick);
        }

        private void ButtonClick(object sender, EventArgs e)
        {
            Console.WriteLine("Button clicked!");
        }

        public void Run()
        {
            button.OnClick();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MainForm mainForm = new MainForm();
            mainForm.Run();
        }
    }
}

在这个示例中,我们定义了两个类,一个名为Button,另一个名为MainFormButton类有一个名为Click的公共事件,表示当按钮被点击时发生的事件。MainForm类将Button实例化,并订阅了Click事件。

MainForm类的ButtonClick方法中,打印了“Button clicked!”的文本。在MainForm类的Run方法中,OnClick方法被调用,从而触发Click事件。因为MainForm已经订阅了Click事件,并且已经实现了ButtonClick方法,所以在按钮被单击时,它将打印“Button clicked!”的文本。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c#委托与事件(详解) - Python技术站

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

相关文章

  • c#数据绑定之向查询中添加参数(.Net连接外部数据库)

    C# 数据绑定之向查询中添加参数(.Net连接外部数据库) 在C#中,我们可以使用.NET连接外部数据库,实现数据绑定等操作。在查询数据时,有时需要向查询中添加参数,以实现更加精准的查询结果。 1. 添加数据库连接 首先,我们需要添加数据库连接,使用SqlConnection类来连接数据库。连接字符串可以通过Visual Studio中的数据源管理器来获取。…

    C# 2023年6月1日
    00
  • C#使用foreach语句搜索数组元素的方法

    当我们需要搜索一个数组中的元素时,可以使用C#中的foreach语句来实现。以下是使用foreach语句搜索数组元素的步骤: 1. 创建一个数组 在开始搜索数组元素之前,需要先创建一个数组,并向其中添加元素。例如,我们要创建一个包含数字1到5的数组,可以使用以下代码: int[] numArray = new int[] {1, 2, 3, 4, 5}; 2…

    C# 2023年6月8日
    00
  • c#中将uint值转换成int的实例方法

    将uint值转换成int的方法有多种,其中一种常用的方法是将uint值强制转换成int类型。这种方法可以利用unchecked代码块确保不会引发数值溢出。 下面是实现这种方法的代码示例: uint uintValue = 1234567890; int intValue = unchecked((int)uintValue); 在上面的代码示例中,我们首先将…

    C# 2023年5月15日
    00
  • 可空类型Nullable用法详解

    可空类型Nullable用法详解 概述 C# 提供了可空类型 Nullable<T> 来表示值类型(例如 int、double 等)可以为 null。可空类型的变量将具有两种可能的状态:1)具有值;2)没有值(null)。 int? myNullableInt = null; // 可空类型 int 的变量,赋值为 null(没有值) 可空类型的…

    C# 2023年5月15日
    00
  • C#中线程同步对象的方法分析

    请看下面的详细讲解。 C#中线程同步对象的方法分析 在多线程编程中,线程同步是必不可少的一部分。C#中提供了多种线程同步对象,本文将对这些对象的使用方法进行分析。 1. ManualResetEvent ManualResetEvent用于在线程间进行信号传递。通常情况下,线程A等待线程B完成某个操作后再进行下一步操作,这时候线程B需要向线程A发信号。Man…

    C# 2023年5月15日
    00
  • C#开启线程的四种方式示例详解

    C#开启线程的四种方式示例详解 为什么要开启线程 在编写程序时,一些任务需要花费较长时间去执行,这时候如果在主线程上执行就会导致界面卡死或程序无响应。此时,我们可以开启线程去执行这些耗时的操作,保证程序的正常运行。 四种方式开启线程 1. Thread类 Thread类是C#中最常用的开启新线程的方式。使用该方式,需要创建一个Thread对象并指定对应的线程…

    C# 2023年6月6日
    00
  • C# Enum.GetValues()方法: 获取枚举类型的所有值

    C#中的Enum.GetValues()是一个方法,它可以用于获取枚举类型中所有可能的值。具体来说,它将返回一个包含枚举类型的所有可能值的数组。下面是更为详细的讲解。 方法作用 Enum.GetValues()主要用于以下两个方面: 获取枚举类型中所有可能的值 将一个枚举类型的所有可能值转换为数组,以方便使用 使用方法 Enum.GetValues()的使用…

    C# 2023年4月19日
    00
  • WindowsForm实现警告消息框的实例代码

    下面是实现警告消息框的完整攻略。 1. 创建Windows Forms应用程序 首先,我们需要在Visual Studio中创建一个Windows Forms应用程序。在“开始界面”中选择“创建新项目”,并选择“Windows Forms应用程序”。 2. 添加控件 在创建应用程序后,我们需要添加控件来实现警告消息框。打开Form1.cs(默认窗体),将工具…

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