使用icode9重学c#系列——委托和匿名函数
作者:互联网
前言
简单介绍一下什么是委托。
正文
以前也写过委托,这次算是重新归档,和新的补充吧。
有些人说委托是函数指针的包装,也有些人说委托是一个方法或多个方法的引用。
这都是没有问题,委托是一个概念,微软官方文档说委托是一种引用类型,表示对具有特定参数列表和返回类型的方法引用。
我觉得太啰嗦了,实际上就是方法的引用。
上面都是委托的概念,但是实现方式每种语言可能都不一样。
比如c++ 和 c 用的是函数指针,而c# 用的是生成包装类(等下IL),当然本质还是函数指针。
那么来看下委托。
internal class Program
{
delegate int TestDelegate(int a);
static void Main(string[] args)
{
TestDelegate a = test;
a(0);
}
public static int test(int a)
{
return 0;
}
}
将test 给了委托a,然后调用的时候直接a()就可以了。
用起来十分简单。
实际上对IL来说其实是没有委托这个概念的,通过反编译来看下原理。
private static void Main(string[] args)
{
TestDelegate a = new TestDelegate(test);
a(0);
}
实际上会生成TestDelegate这样一个类,然后将test 引用添加进去。
再看下TestDelegate是一个什么样的类。
就是把调用的object 和 法的引用放入包装类中了,然后invoke 可以进行调用。
如果是多个方法的引用呢?
internal class Program
{
delegate int TestDelegate(int a);
static void Main(string[] args)
{
TestDelegate a = test;
a += test;
a(0);
}
public static int test(int a)
{
return 0;
}
}
原理就是又new了一个TestDelegate,然后用Delegate 将两个相连。
Combine 是一个静态方法哈
本质是调用a的combineImp这个方法。之所以有这个一个静态方法是为了避免出现a为空的情况,如果a为空,直接把b给a啊。
这个是我们写链式结构可以学习的,这样就不用判断声明的时候是否为空。
然后c# 帮我们提取定义了很多委托,以至于我们几乎不用去声明委托。
比如Func 和 Action,Func 有返回值,Action没有。