概述
C#
的委托是一种类型安全的函数指针,用于引用方法,委托允许方法作为参数传递,或者将方法赋值给委托变量,并通过委托调用方法。
委托类型:委托定义了方法的的签名([方法的参数类型和返回值]
),所以,委托只能引用符合签名的方法。
委托实例:委托是一个引用类型,可以实例化并指向一个或多个符合委托签名的方法。
多播委托:C#
支持将多个方法绑定到一个委托实例中,这种委托称为“多播委托”,可以依次调用这些方法。
委托声明
自定义委托的声明使用delegate
关键字,类似于方法的签名,但是它是一个[类型]
,指定了返回值以及参数类型。
public delegate int CustomDelegate(int x,int y);
CustomDelegate
是委托的类型,可以引用任何为 int Method(int x ,int y)
的方法,注意返回值和参数类型要一致。
委托使用
以图片处理为例,假设封装了一个图片处理的SDK
给三方做二次开发,如果三方想拓展图片处理的方法,使用委托方式更方便。
首先新建图片类。
public class Image
{
string Name { set; get; }
}
处理图片的方法都放在ImageTools
类中,封装成SDK
给三方使用,有以下处理方法。
public class Tools
{
public void ImageFilters(Image image)
{
Console.WriteLine("[工具箱]-添加滤镜");
}
public void AdjustColor(Image image)
{
Console.WriteLine("[工具箱]-调整颜色");
}
public void Beautification(Image image)
{
Console.WriteLine("[工具箱]-美颜");
}
public void ImageResize(Image image)
{
Console.WriteLine("[工具箱]-调整尺寸");
}
public void LoadImage(string name)
{
Console.WriteLine("[工具箱]-加载图片");
}
public void SavePhoto()
{
Console.WriteLine("[工具箱]-保存图片");
}
}
SDK
中对图片处理的能力还是不够强大,比如对图片的旋转、图片压缩或者对图片格式的修改方法都没有提供。图片处理类中声明委托ImageProcessorHandler
属性,在处理方法中作为形参传入。
//声明委托
public delegate void ImageProcessorHandler(Image image);
public class ImageProcessor
{
public static void Process(Image image, ImageProcessorHandler processorHandler) {
// processorHandler(image);
processorHandler.Invoke(image);
}
上述定义的委托格式ImageProcessorHandler(Image image)
,所以拓展方法只要按void Method(Image image)
这种格式定义就可以轻松拓展其他图片处理方法。
internal class Program
{
//三方拓展图片格式修改方法
private static void ChangeFormat(Image image) {
Console.WriteLine("更改图片为png格式");
}
private static void Main(string[] args)
{
Image image = new();
Tools tools = new();
tools.LoadImage("test.jpg");
//调用SDK中默认的图片处理方法
ImageProcessorHandler handler = tools.ImageFilters;
handler += tools.ImageResize;
handler += tools.Beautification;
handler += tools.AdjustColor;
//调用三方拓展方法
handler += ChangeFormat;
//图片处理
ImageProcessor.Process(image, handler);
tools.SavePhoto();
}
}
查看主函数中委托的调用,我们发现使用了+=
运算符,说明一个委托可以指向多个方法,多个方法添加到委托实例中,委托会按照添加顺序依次执行,这就是委托的多播模式。
C#
中也提供了一些内置的委托类型,常用的有System.Action
、System.Func
等。以System.Action
为例
//声明委托
//public delegate void ImageProcessorHandler(Image image);
public class ImageProcessor
{
public static void Process(Image image, Action<Image> processorHandler) {
processorHandler.Invoke(image);
}
}
private static void Main(string[] args)
{
.....
Action<Image> handler = tools.ImageFilters;
handler += tools.ImageResize;
handler += tools.Beautification;
handler += tools.AdjustColor;
handler += ChangeFormat;
.....
ImageProcessor.Process(image, handler);
}
委托与事件
事件是C#
中的一种特殊委托,它用于提供一种机制来实现发布-订阅模式,允许对象在某个条件或状态改变时通知其他对象。委托是事件的基础,事件相当于委托的封装。