一、委托
C#中的委托其实就是C++的函数指针,在程序运行时可以使用它们来调用不同的函数。它代表了对一个或多个方法的引用。委托允许将方法作为参数传递、存储对方法的引用以及调用这些方法。它在事件处理、回调和异步编程等方面非常有用。
以下是一些关于C#委托的基本概念和用法:
-
定义委托: 可以使用
delegate
关键字来定义委托。委托定义指定了委托可以引用的方法的签名。例如:delegate int MathOperation(int a, int b);
-
实例化委托: 委托是对象,因此您需要实例化它。您可以将委托实例化为引用特定方法,方法必须与委托的签名匹配。例如:
MathOperation add = (a, b) => a + b; MathOperation subtract = (a, b) => a - b;
-
调用委托: 通过使用委托实例来调用与之关联的方法,就好像调用一个方法一样。例如:
int result = add(5, 3); // 调用add委托,将结果存储在result变量中
-
多播委托: 委托还支持多播(Multicast)功能,即一个委托可以引用多个方法。多个方法按照委托的顺序依次调用。例如:
MathOperation multiOperation = add + subtract; // 多播委托 int result = multiOperation(10, 5); // 会依次调用add和subtract方法
-
委托作为方法参数: 委托可以作为方法的参数,这允许您将方法作为参数传递给其他方法,例如在事件处理中。
-
内置委托类型: C#中有一些内置的委托类型,如
Action
和Func
,它们是泛型委托,用于处理不同参数和返回值类型的方法。
下面是一个简单的示例,展示了委托的基本用法:
二、事件
C#中的事件是一种特殊的委托,它用于实现观察者设计模式,允许一个对象(事件源)通知其他对象(事件处理程序或订阅者)某个事件已经发生。事件通常与委托一起使用,但它们提供了一种更安全和封装的方式来实现事件处理。可以说,事件是受限制的委托。
以下是关于C#事件的基本概念和用法:
-
定义事件: 事件是通过使用
event
关键字定义的。事件通常与一个特定的委托类型关联,该委托类型用于表示事件处理程序的方法签名。例如(其中EventHandler是一个委托类型
):public event EventHandler MyEvent;
上面的代码定义了一个名为
MyEvent
的事件,它使用EventHandler
委托来表示事件处理程序的方法。 -
订阅事件: 其他对象可以订阅事件,以便在事件发生时接收通知。订阅事件时,通常会将事件处理程序的方法添加到事件的委托列表中。例如:
someObject.MyEvent += MyEventHandlerMethod;
-
触发事件: 事件源可以通过调用事件来触发事件。触发事件时,事件源会调用事件的委托列表中的每个方法。例如:
MyEvent?.Invoke(this, EventArgs.Empty);
在上述示例中,
MyEvent
是一个事件,通过?.Invoke
调用来触发事件,并传递事件源和事件参数。 -
取消订阅事件: 对象可以随时取消对事件的订阅,以停止接收事件通知。取消订阅使用
-=
操作符。例如:someObject.MyEvent -= MyEventHandlerMethod;
事件通常用于实现松散耦合的应用程序组件之间的通信,其中一个组件(事件源)可以触发事件,而其他组件(事件处理程序)可以根据需要订阅或取消订阅事件,以响应事件发生时的通知。
下面是一个简单的示例,演示了如何定义、订阅、触发和取消订阅事件:
using System;
class Program
{
public event EventHandler MyEvent; // 定义事件
public void RaiseEvent()
{
MyEvent?.Invoke(this, EventArgs.Empty); // 触发事件
}
static void Main()
{
Program program = new Program();
program.MyEvent += MyEventHandler; // 订阅事件
program.RaiseEvent(); // 触发事件
program.MyEvent -= MyEventHandler; // 取消订阅事件
Console.ReadKey();
}
static void MyEventHandler(object sender, EventArgs e)
{
Console.WriteLine("Event handled!");
}
}
在上述示例中,Program
类定义了一个事件MyEvent
,然后在Main
方法中订阅、触发和取消订阅事件,以演示事件的基本用法。事件处理程序MyEventHandler
在事件触发时被调用。
三、事件与委托的区别
事件是受限的委托,是一种订阅(可以在外部+= -=)/发布(只能在内部触发)机制,
事件在外部订阅(+=或者-=但不能使用=),然后只能由持有该事件的内部类去触发这个事件,那么对应的内部类或外部类订阅了这个事件的所有方法都会被触发调用。而委托可以随时在外部订阅,外部或内部触发都可以。
委托 | 事件 | |
---|---|---|
定义 | 委托是一种类,是一种类型 | 事件可以被看作一个委托类型的变量 |
区别 | 委托可以定义在类的内部或者外部 | 事件只能定义在类的内部(否则编译期间就会报错) |
区别 | 委托可以作为方法的参数传递 | 事件不能作为方法的参数传递 |
区别 | 委托可以使用±赋值,也可以使用=赋值 | 事件只能使用±赋值,不能使用= |
区别 | 委托可以在外部类触发 | 事件只能在声明事件的内部类里面触发 |
用途区别 | 委托常用于实现回调函数的机制 | 事件通常用于实现观察者模式(也称为发布/订阅模式) |
PS.回调函数
回调函数就是把一个方法传给另外一个方法去执行(一般都是作为参数传给另一个函数,然后在该函数内部调用)。在C#有很多回调函数,比如异步操作的时候。当处理完某个事情之后,再调用先前传过来的回调函数。