C#基础:委托

委托是C#中最为常见的内容。与类、枚举、结构、接口同样,委托也是一种类型。类是对象的抽象,而委托则能够当作是函数的抽象。一个委托表明了具备相同参数列表和返回值的全部函数。好比:异步

view plaincopy to clipboardprint?
  1. delegate int GetCalculatedValueDelegate(int x, int y);  

在上面的定义中,咱们定义了一个委托,这个委托表明着一类函数,这些函数的第一个参数是整数型的x,第二个参数是整数型的y,而函数的返回值则是一个整数。在这里,为了描述方便,咱们把这一类的函数称为具备相同签名(signature)的函数(注意:这个签名并非数字签名中的概念,而只是表示这类函数具备相同的参数列表和返回值)。函数

既然委托是一种类型,那么它就能被用来定义参数、变量以及返回值。由委托定义的变量用于保存具备相同签名的函数实体。须要注意的是,C#和C++不一样,C++中的函数指针只能保存全局的或者静态的函数,而C#中的委托实体则能够指代任何函数。spa

如今咱们来看一个例子,在这个例子中,咱们使用了上面定义的那个委托,并建立了一个委托实体,使其指代程序中的AddCalculator函数,接下来就能够直接像使用函数自己同样,使用这个委托实体来得到计算的结果。线程

view plaincopy to clipboardprint?
  1. delegate int GetCalculatedValueDelegate(int x, int y);   
  2.   
  3. static int AddCalculator(int x, int y)   
  4. {   
  5.     return x + y;   
  6. }   
  7.   
  8. static int SubCalculator(int x, int y)   
  9. {   
  10.     return x - y;   
  11. }   
  12.   
  13. static void Main(string[] args)   
  14. {   
  15.     GetCalculatedValueDelegate d = AddCalculator;   
  16.     Console.WriteLine(d(10, 20));   
  17. }   

到这里也就能基本上明白“委托”的意义了,针对上面的Main函数,原本须要调用AddCalculator函数的,却经过d来调用了,也就是,后续对AddCalculator的操做由d代为效劳。原本是要小明去老师办公室拿粉笔盒的,因为小明和小文是好朋友,所以小明就要小文代他去拿,因而小文成了小明的代理,小明委托小文去拿粉笔盒。代理

如今咱们来考虑委托做为参数的情形。将委托做为参数,能够把函数自己的处理逻辑抽象出来,而让调用者决定最终使用什么样的逻辑去处理。请看下面的例子:指针

view plaincopy to clipboardprint?
  1. delegate int GetCalculatedValueDelegate(int x, int y);   
  2.   
  3. static int AddCalculator(int x, int y)   
  4. {   
  5.     return x + y;   
  6. }   
  7.   
  8. static int SubCalculator(int x, int y)   
  9. {   
  10.     return x - y;   
  11. }   
  12.   
  13. static int Calculator(GetCalculatedValueDelegate del, int x, int y)   
  14. {   
  15.     return del(x, y);   
  16. }   
  17.   
  18. static void Main(string[] args)   
  19. {   
  20.     Console.WriteLine(Calculator(AddCalculator, 10, 20));   
  21. }   

在上面的例子中,Calculator函数的第一个参数就是一个委托。事实上,Calculator对x和y将会作什么处理,它自己并不知道,如何处理x和y由GetCalculatedValueDelegate来决定。那么在Main方法里,咱们将AddCalculator方法做为参数传递给Calculator,表示让Calculator用AddCalculator的逻辑去处理x和y。这也很形象:Calculator说:“我不知道要怎么处理x和y,让del去处理好了!”因而就把x和y扔给了del。对象

这种作法其实跟“模板方法模式”有点点相似。在模板方法模式中,能够将可变的部分留给子类去重写,而将不变的部分由父类实现。那么在委托做为参数的状况下,Calculator能够本身处理不变的逻辑,而将“具体怎么作”的事情委托给他人去办理。接口

委托做为参数,在C#中很是常见。好比线程的建立,须要给一个ThreadStart或者ParameterizedThreadStart委托做为参数,而在线程执行的时候,将这个参数所指代的函数用做线程执行体。再好比:List<T>类型的Find方法的参数也是一个委托,它把“怎么去查找”或者说“怎么样才算找到”这个问题留给了开发人员。开发人员只须要定义一个参数为T,返回值为布尔型的函数,实现函数体,并将函数做为参数传给Find方法,就能够完成集合中元素的查找。事件

委托做为返回值通常会用在“根据不一样状况决定使用不一样的委托”这样的情形下。这有点像工厂模式,不过委托用做返回值仍是用的没有用做参数这样频繁。ip

与委托相关的概念还有不少,好比异步调用、泛型委托、匿名方法、Lambda表达式、事件、协变与逆变等。我会在后续的文章中陆续介绍。

相关文章
相关标签/搜索