一、委托(delegate)介绍
委托又称为代理或者代表,它是一种动态调用方法的类型,它与类、接口和数组相同,也是引用类型。
委托可以通过引用单个或者多个方法,来代理执行这些方法。
也就是说,委托可以间接调用一个或者多个方法,相当于一个人帮忙做了多个人的活。
二、定义委托类型
委托类型的定义格式如下(关键字:delegate):
[访问修饰符] delegate 返回值类型 委托名([参数列表]);
那么,举两个例子:
/*定义了一个返回值为int的,参数列表为两个int类型的,名称为Calculate的委托*/
public delegate int Calculate(int x,int y);
/*定义了一个返回值为void的,参数列表为一个string类型的,名称为Say的委托*/
public delegate void Say(string name);
三、创建委托对象和引用方法
在前面的介绍我们说过,委托是一种引用类型,那么我们当然就可以去创建一个委托类型的对象。
特别要注意的两点:
- 创建委托类型的对象一定要传入你要引用的方法的方法名
- 被引用的方法的返回值类型以及参数列表必须与委托类型所定义的保持一致
现在,我们定义了一个类,名字叫做“Calculator”,用于处理简单的数学计算,在这个类里面我们分别定义一个Plus方法和Minus方法,这两个方法的返回值都是int类型。然后我们通过委托来引用这两个方法以实现调用。
using System;
namespace ConsoleApp1
{
internal class Program
{
//定义委托类型
public delegate int DelegateFun(int x, int y);
static void Main(string[] args)
{
//创建一个Calculator对象
Calculator calculator = new Calculator();
//创建一个DelegateFun的委托对象fun1,并引用calculator的Plus方法
DelegateFun fun1 = new DelegateFun(calculator.Plus);
//创建一个DelegateFun的委托对象fun2,并引用calculator的Minus方法
DelegateFun fun2 = new DelegateFun(calculator.Minus);
Console.ReadKey();
}
}
//定义类Calculator
public class Calculator
{
public int Plus(int x,int y)
{
Console.WriteLine("执行加法");
return x+y;
}
public int Minus(int x,int y)
{
Console.WriteLine("执行减法");
return x-y;
}
}
}
有同学会疑问:“诶?为什么在创建委托对象的时候,传入的参数是一个方法名,而不是两个int型的值呢?”
这个问题问得好,实际上,在定义委托类型的时候,其 返回值类型 和 参数列表 是给引用的方法提供一个“引用规范”。
就比如上述的代码中,委托类型的返回值类型是int,参数列表是(int x,int y);那么被引用的方法的返回值类型也必然是int,参数列表也必然是(int x,int y),这就是提供了一个“引用规范”。
四、调用委托对象
当我们的委托对象引用了方法之后,那就可以通过委托对象来调用方法了呀。
我们续写之前的代码:
using System;
namespace ConsoleApp1
{
internal class Program
{
//定义委托类型
public delegate int DelegateFun(int x, int y);
static void Main(string[] args)
{
//创建一个Calculator对象
Calculator calculator = new Calculator();
//创建一个DelegateFun的委托对象fun1,并引用calculator的Plus方法
DelegateFun fun1 = new DelegateFun(calculator.Plus);
//创建一个DelegateFun的委托对象fun2,并引用calculator的Minus方法
DelegateFun fun2 = new DelegateFun(calculator.Minus);
//调用委托,像调用方法一样,传入参数即可。由于有返回值,因此定义变量来存储返回值
int result1 = fun1(3,5);
int result2 = fun2(3,5);
//输出结果
Console.WriteLine("fun1执行结果为{0},fun2执行结果为{1}",result1,result2);
Console.ReadKey();
}
}
//定义类Calculator
public class Calculator
{
public int Plus(int x,int y)
{
Console.WriteLine("执行加法");
return x+y;
}
public int Minus(int x,int y)
{
Console.WriteLine("执行减法");
return x-y;
}
}
}
五、匿名委托
在C#当中,也支持定义一种传入匿名方法的委托,也叫“匿名委托”。
它的定义格式如下:
委托类型 委托变量名 = delegate([参数列表]){代码块};
举个例子:
//定义委托类型
public delegate int delegateTest(int x,int y);
//定义一个匿名委托对象
delegateTest del = delegate(int x,int y){
return x+y;
};
六、多路委托(多播委托)
在上面讲述的内容中,我们讲的都是一个委托引用一个方法,这种我们称之为“单路委托”。这样的委托看起来是不是显得很多余?还不如直接调用方法来得更快。
而实际上,一个委托对象支持引用多个方法,这样我们就可以实现用一个委托就可以同时调用多个方法,也就是这一节要说的“多路委托”,也叫做“多播委托”。
1.委托的组合
要做到多路委托之前,我们先学习一下委托的组合。
在两个委托对象之间,我们可以通过“+”来实现组合(类似于数学上的加法一样)。
这里我依旧使用前面所定义的委托类型和Calculator类来讲解:
//定义一个Calculator对象
Calculator calculator = new Calculator();
//定义一个DelegateFun委托对象,并引用calculator的Plus方法
DelegateFun fun1 = new DelegateFun(calculator.Plus);
//定义一个DelegateFun委托对象,并引用calculator的Minus方法
DelegateFun fun2 = new DelegateFun(calculator.Minus);
//将两个同类委托对象进行组合
fun1 = fun1+fun2;
//调用委托
fun1(5,5);
在这上面的代码中,有两个相同类型但是引用自不同方法的委托对象,分别是fun1和fun2。
通过使用“+”,我们把fun1和fun2组合到一起了,然后又赋值给fun1,这样fun1和fun2就组合到一起了。而当我们再次去调用fun1这个委托对象的时候,它就会同时执行fun1在创建时引用的方法以及fun2在创建时引用的方法。
2.实现多路委托
其实在前面说的委托的组合之后,我又暗示了“类似于数学上的加法”,那么我们可以举一反三得出使用“+=”来进行多个委托的组合,从而实现多路委托。
在这里注意两个要点:
- 通过“+=”运算符将新创建的委托对象添加到委托调用列表中。
- 通过“-=”运算符来移除调用列表中的委托对象
这里我们来实现以下多路委托:
using System;
namespace ConsoleApp1
{
internal class Program
{
///定义委托
public delegate int DelegateFun(int x, int y);
static void Main(string[] args)
{
//定义一个Calculator对象
Calculator calculator = new Calculator();
//定义一个DelegateFun委托对象
DelegateFun fun = new DelegateFun(calculator.Minus);
//使用+=来添加委托,相当于new了一个新的委托然后组合到委托对象当中
fun += new DelegateFun(calculator.Plus);
//使用+=来添加委托
fun += new DelegateFun(calculator.Multiply);
//获取返回值
int result = fun(3, 6);
//输出返回值
Console.WriteLine(result);
Console.ReadKey();
}
//定义类Calculator
public class Calculator
{
public int Plus(int x, int y)
{
Console.WriteLine("执行加法");
return x + y;
}
public int Minus(int x, int y)
{
Console.WriteLine("执行减法");
return x - y;
}
public int Multiply(int x,int y)
{
Console.WriteLine("执行乘法");
return x * y;
}
}
}
}
在上面的代码我们可以看得到,我使用了+=以及通过new DelegateFun的方式来添加要引用的方法,这样的好处就是不需要定义太多的委托对象,定义一个就可以了。
同理,如果你想移除掉对某一个方法的引用,用-=就可以了:
fun -= calculator.Multiply;
3.多路委托的返回值
我们给委托对象引用了这么多个方法,那么在调用委托对象的时候,这个委托对象所返回的值到底是哪个?
回答:委托对象所返回的值是最后一次引用的那个方法所返回的值。
就比如上述的所实现的多路委托,在调用委托对象的时候,返回的值就是calculator.Multiply(3,6)所得到的值,也就是3*6 = 18。(可以自行去测试一下)
好啦,上述的就是C#委托的全部讲解啦,如果这篇文章对你有帮助的话,还请点个赞哦,谢谢!