C# 委托

定义

C#中的委托(Delegate)类似于C或 C++ 中的函数指针,是一种引用类型,表示对具有特定参数列表和返回类型的方法的引用。

委托经常适用于、实现事件和回调方法,所有的委托都派生自System.Delegate类。

在实例化委托时,可以将委托的实例与具有相同参数列表与返回值类型的方法相关联,然后就可以通过委托实例来调用方法。使用委托还可以将方法作为参数传递给其他方法。

特点

委托具有以下特点:

  • 委托是完全面向对象的,委托是同时封装对象实例和方法;
  • 委托允许将方法作为参数进行传递;
  • 委托可用于定义回调方法;
  • 委托可以将多个方法链接在一起;
  • 方法不必与委托类型完全匹配:
  • C# 2.0版引入了匿名函数的概念,可以将代码块作为参数(而不是单独定义的方法)进行传递。C#3.0引入了Lambda 表达式,利用它们可以更简练地编写内联代码块。匿名方法和Lambda 表达式都可编译为委托类型,这些功能现在统称为屠名函数。

委托使用

声明

声明委托需要使用 delegate 关键字,语法如下:

csharp 复制代码
delegate 返回值类型 委托名(参数表..)
delegate int calculate(int a,int b);
delegate void showMsg(string msg);

委托可以引用与委托具有相同签名的方法,也就是说委托在声明时即确定了委托可以引用的方法。

相同签名:方法的返回值类型、参数类型、参数个数、参数顺序 都完全相同,并不是方法名与委托名相同。

实例化

委托声明后,可用new关键字来实例化,即创建委托对象,将其与特定的方法关联。

csharp 复制代码
delegate int Calculate(int a,int b);//声明一个计算的委托
//提供两个与之对应的方法
public int Add(int a,int b)
{
    return a+b;
}
public int subtract(int a,int b)
{
    return a-b;
}
public void Test()
{

    //实例化委托
    Calculate add=new Calculate(Add);//创建委托对象,并与Add方法关联
    Ca]culate subtract=new Calculate(Subtract);//创建秀托对象,并与Subtract方法关朕
    //委托调用
    int sum= add(10,20);//30
    int dvalue=subtract(20,5);//15
}

委托还可以通过将方法签名赋给委托变量。

ini 复制代码
Calculate addl=Add;
int suml=add1(30,5);//35

多播委托

委托对象可使用"+="运算符合并多个委托。只有相同类型的委托可被合并。使用"-"运算符可用于从合并的委托中移除委托。

使用委托的这个特点,可以创建一个委托被调用时要调用的方法列表,这被称为委托的多播(multicasting)。

多播委托应用于:一个动作触发一连串的的操作。

csharp 复制代码
delegate void showMsg(string msg);//声明一个显示信息的委托
//提供对应类型的方法
public void writeMsg(string msg)
{
    Console.WriteLine("显示的消息内容:"+msg);
}

public void PrintMsg(string msg)
{
    Console.write("输出的消息:"+msg+"\n");
}

public void Test()
{
    ShowMsg printl= WriteMsg;
    print1 += PrintMsg;
    print1 -= PrintMsg; // 委托移除
    print1 += PrintMsg;
    print1("欢迎来到课堂!");
 }
//输出---先执行writeMsg方法,再执行PrintMsg
显示的消息内容:欢迎来到课堂!
输出的消息:欢迎来到课堂!

如果多播委托调用的一系列方法都是有返回值,只会得到最后一个方法的执行结果。

csharp 复制代码
delegate doube calculate(double dl,double d2);//声明一个计算的委托
//提供对应类型的方法public double Add(double a,double b)
{
    return a+b;
}
public double Multiply(double a,double b)
{
    return a*b;
}
public double Divide(double a,double b)
{
    return a/b;
}
public void Test()
{
    Calculate cal= Add;
    cal += Multiply;
    cal += Divide;
    double resu1t=cal(6.2,3.1);//2
}
相关推荐
武子康2 小时前
Java-72 深入浅出 RPC Dubbo 上手 生产者模块详解
java·spring boot·分布式·后端·rpc·dubbo·nio
椰椰椰耶3 小时前
【Spring】拦截器详解
java·后端·spring
brzhang4 小时前
我操,终于有人把 AI 大佬们 PUA 程序员的套路给讲明白了!
前端·后端·架构
wan_da_ren7 小时前
JVM监控及诊断工具-GUI篇
java·开发语言·jvm·后端
【本人】7 小时前
Django基础(一)———创建与启动
后端·python·django
lifallen7 小时前
Kafka 时间轮深度解析:如何O(1)处理定时任务
java·数据结构·分布式·后端·算法·kafka
你的人类朋友8 小时前
【✈️速通】什么是SIT,什么是UAT?
后端·单元测试·测试
程序无bug10 小时前
后端3行代码写出8个接口!
java·后端
绝无仅有10 小时前
使用LNMP一键安装包安装PHP、Nginx、Redis、Swoole、OPcache
后端·面试·github
他日若遂凌云志10 小时前
C++ 与 Lua 交互全链路解析:基于Lua5.4.8的源码剖析
后端