当前位置: 首页> 科技> 数码 > C# --- 委托(Delegates)和事件(Events)

C# --- 委托(Delegates)和事件(Events)

时间:2025/9/16 18:02:04来源:https://blog.csdn.net/qq_53839898/article/details/141356579 浏览次数:0次

5.1 委托(Delegates)

> 1 委托是C#中非常强大的特性,类似于C++中的函数指针,但更加类型安全和灵活。委托可以引用一个方法,或者一组方法,当调用委托时,它会执行引用的方法。委托特别适合用于实现回调机制和事件驱动编程。

> 2 想象一下,你是一位活动策划师,你需要组织一场大型活动。在活动中,有很多不同的任务需要完成,比如安排音乐、布置场地、准备食物等等。你可以自己去做所有的事情,但更好的方法是让专业人士来帮你完成这些任务。

委托在编程中就像是这些专业人士。你可以把一个任务委托给一个方法,当需要完成这个任务时,你只需要调用这个委托,而不需要知道具体是哪个方法在执行任务。委托是一种类型安全的函数指针,可以指向一个或多个方法,并在需要时调用它们。

5.1.1 委托的定义和使用

(1) 定义委托:public delegate void MyDelegate(string message);

(2) 声明和实例化委托:

> (1) MyDelegate del = new MyDelegate(MethodB);

> (2) MyDelegate del = MethodB;

以上两种实例方式的效果和意义是一样的,都是将 MethodB 分配给一个新的 MyDelegate 类型的委托实例。不同的是,第一种方式显式地使用了 new 关键字来创建委托实例,而第二种方式是语法糖,编译器会自动将其转换为第一种方式。

(3) 使用委托:del("Hello, World!");

5.1.2 示例

// 定义一个委托类型,名为 MyDelegate,接受一个字符串参数并返回 void
public delegate void MyDelegate(string message);
class Program
{static void Main()
{// 声明和实例化委托,并将 MethodA 分配给它MyDelegate del = MethodA;// 调用委托,实际调用 MethodA 方法del("Hello from MethodA");// 将委托指向 MethodBdel = MethodB;// 调用委托,实际调用 MethodB 方法del("Hello from MethodB");
}// 符合委托签名的方法 MethodA
static void MethodA(string message)
{Console.WriteLine(message);
}// 符合委托签名的方法 MethodB
static void MethodB(string message)
{Console.WriteLine(message);
}

在这个示例中,MyDelegate是一个委托类型,它可以引用任何接受一个字符串参数并返回void的方法。MethodA和MethodB是两个符合该签名的方法,我们可以将它们分配给del委托并调用它们。

5.1.3 拓展

(1)自定义委托

// 定义一个自定义委托类型
public delegate int AddDelegate(int x, int y);class Program
{static void Main(){// 使用自定义委托类型AddDelegate add = (x, y) => x + y;Console.WriteLine(add(2, 3)); // 输出 5}
}

> 相等于  ---》 (2) Func 委托

class Program
{static void Main(){// 使用 Func 委托Func<int, int, int> add = (x, y) => x + y;Console.WriteLine(add(2, 3)); // 输出 5}
}

> 详细解释

.    Func<int, int, int>:

..   第一个 int:表示方法的第一个参数的类型。

...  第二个 int:表示方法的第二个参数的类型。

.... 第三个 int:表示方法的返回值的类型。

5.1.4 多播委托

多播委托是 C# 中的一种特殊委托类型,它允许一个委托实例包含对多个方法的引用。当调用该委托时,它会依次调用所有被引用的方法。多播委托在事件处理和回调机制中非常有用。

(1) 特点

.   多个方法调用:多播委托可以包含对多个方法的引用,当调用该委托时,会按顺序调用所有方法。

..  顺序执行:多播委托中的方法按添加顺序执行。

... 返回值处理:如果委托有返回值,多播委托只返回最后一个方法的返回值。

(2) 创建多播委托

可以使用 += 操作符将多个方法附加到一个委托实例上,使用 -= 操作符从委托实例中移除方法。

(3) 定义和使用多播委托

using System;// 定义一个委托类型,接受一个字符串参数并返回 void
public delegate void MyDelegate(string message);class Program
{static void Main(){// 声明一个 MyDelegate 类型的委托实例,并将 MethodA 分配给它MyDelegate del = MethodA;// 使用 += 操作符将 MethodB 附加到委托实例 del 上del += MethodB;// 调用委托实例 del,将依次调用 MethodA 和 MethodB,传递参数 "Hello from Delegate"del("Hello from Delegate");   //MethodA和MethodB都输出// 使用 -= 操作符从委托实例 del 上移除 MethodAdel -= MethodA;// 再次调用委托实例 del,这次只会调用 MethodB,传递参数 "Hello again"del("Hello again");  //只输出MethodB}// 定义符合委托签名的第一个方法 MethodAstatic void MethodA(string message){Console.WriteLine("MethodA: " + message);}// 定义符合委托签名的第二个方法 MethodBstatic void MethodB(string message){Console.WriteLine("MethodB: " + message);}
}

(4) 处理返回值的多播委托

using System;using System.Collections.Generic;// 定义一个返回整数的委托类型,接受一个整数参数
public delegate int MyDelegate(int value);class Program
{static void Main(){// 声明一个 MyDelegate 类型的委托实例,并将 MethodA 和 MethodB 分配给它MyDelegate del = MethodA;del += MethodB;// 调用委托并获取所有返回值List<int> results = InvokeDelegate(del, 5);// 输出所有返回值Console.WriteLine("Results:");foreach (int result in results){Console.WriteLine(result);}}// 定义符合委托签名的第一个方法 MethodAstatic int MethodA(int value){return value + 1; // 将输入值加 1}// 定义符合委托签名的第二个方法 MethodBstatic int MethodB(int value){return value + 2; // 将输入值加 2}// 定义一个方法来调用多播委托并收集所有返回值static List<int> InvokeDelegate(MyDelegate del, int value){List<int> results = new List<int>();// 使用 GetInvocationList 获取委托的调用列表foreach (MyDelegate handler in del.GetInvocationList()){// 调用每个方法,并将返回值添加到 results 列表中int result = handler(value);results.Add(result);}return results;}
}

5.2 事件(Events)

事件是基于委托的一种特殊成员,主要用于在一个对象希望通知另一个对象某些事情发生时使用。事件是一种发布-订阅模式的实现,通常用于UI编程和处理用户交互。

5.2.1 定义和使用事件

(1) 定义事件:

public event MyDelegate MyEvent;

(2) 触发事件:

protected virtual void OnMyEvent(string message)

{

    if (MyEvent != null) MyEvent(message);

}

(3) 订阅事件:

obj.MyEvent += new MyDelegate(EventHandler);

5.1.2 示例

public delegate void MyDelegate(string message);class Publisher
{public event MyDelegate MyEvent;public void RaiseEvent(string message){if (MyEvent != null) MyEvent(message);}
}
class Subscriber
{public void EventHandler(string message){Console.WriteLine("Event received: " + message);}
}
class Program
{static void Main(){Publisher publisher = new Publisher();Subscriber subscriber = new Subscriber();// 订阅事件publisher.MyEvent += subscriber.EventHandler;// 触发事件publisher.RaiseEvent("Hello, Event!");}
}

在这个示例中,Publisher类定义了一个事件MyEvent,当事件触发时会调用所有订阅的处理程序。Subscriber类有一个EventHandler方法,它将被注册为事件处理程序。Publisher对象触发事件时,Subscriber对象的处理程序被调用。

> 委托是对方法的引用,可以存储和调用方法。适用于实现回调机制。

> 事件是基于委托的,用于实现发布-订阅模式,适用于通知其他对象某些事情发生。

关键字:C# --- 委托(Delegates)和事件(Events)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: