C#语法——委托,架构师必修


C#语法——委托,架构师必修

文章插图

C#语法——委托,架构的血液本篇文章主要介绍委托的应用 。
委托是大家最常见的语法了,但会用与精通之间的差别是巨大的 。
一个程序员如果不能精通委托,那么,他永远无法成为一个架构师 。
所以,委托是必须掌握的技能之一 。
委托的定义什么是委托?
委托实际上是一种类型,是一种引用类型 。
微软用delegate关键字来声明委托,delegate与int,string,double等关键字一样 。都是声明用的 。
下面先看下声明代码,这里声明了两个委托 。
public delegate void TestDelegate(string message);public delegate int TestDelegate(MyType m, long num);delegate既然是关键字,和int,string一样,那么,为什么delegate后又跟了一个void或者int呢?
如果他们是同等地位的关键字,为什么可以一起使用呢?
很简单,我们把delegate后面的 【void TestDelegate(string message)】理解为一个变量,是不是就清晰明了了一些 。
我们把delegate关键字理解为,是用来专门来定义这种复杂的变量的 。而这种复杂的变量可以包含一个返回值和任意数目任意类型的传入参数 。
有没有感觉,这个复杂的变量特别像一个函数的定义 。
没错,官方定义,委托类型的声明与方法签名相似 。所以,这个复杂变量,的确,书写的方式就是与函数一样 。
那么,为什么这个声明方式如此怪异呢,是因为,我们用delegate定义的变量,只能用函数赋值 。赋值方式如下所示:
public delegate void TestDelegate(string message);public delegate long TestDelegate2(int m, long num);public static void Excute(){ TestDelegate2 td = Double; } static long Double(int m, long num){ return m * num;}委托的基本应用
学会了赋值以后,我开始使用委托 。
委托的使用方式如下:
public static void Excute(){TestDelegate2 td = Double; string result = td(51, 8);Console.WriteLine(result);} 这里我们会发现,委托的使用方式与函数调用一样 。
没错,它们的确是一样的 。因为委托是用函数来赋值的,所以调用方式一样也并不奇怪,不是吗 。
换一种说法,就是委托封装了一个函数 。
如果委托是封装的函数,并且它又是引用类型 。那么委托第一种常规的应用就浮现出来了 。
那就是——引用类型的函数 。
如果函数是引用类型,那么这个函数只要没被内存回收,就可以被调用 。如果是public函数或者是public static函数,那么它能跨越的东西就更多了 。
比如可以跨类调用,跨程序集调用等等 。而这种用法,就是委托的基本应用 。
匿名委托的应用
匿名委托的官方介绍:在 2.0 之前的 C# 版本中,声明委托的唯一方式是使用命名方法 。C# 2.0 引入匿名方法,在 C# 3.0 及更高版本中,Lambda 表达式取代匿名方法作为编写内联代码的首选方式 。
看不懂没关系,我们直接来学习使用 。代码如下:
delegate string anonymousDelegate(int m, long num);public static void Excute(){ anonymousDelegate ad = delegate (int m, long num) { return m.ToString() + num.ToString(); };//2.0时代的匿名委托 anonymousDelegate ad2 = (m, num) => { return m.ToString() + num.ToString(); };//3.0以后匿名委托 }如代码所示,匿名委托也叫Lambda表达式,不懂的同学就当它是有固定写法即可,不用讲什么道理,只要记住并应用即可 。
匿名委托虽然减少了一点代码,但还是要求我们自己去声明委托 。所有,还能再简写一点吗?
答案当然是,可以的 。
Action与FuncAction与Func是微软为我们预先定义好了的,两个委托变量 。其中Action是不带返回值的委托,Func是带返回值的委托 。
可以说,Action与Func完全包含了,我们日常使用所需的,全部的,委托变量 。
也就是说,我们可以不用再去自己手动声明委托了 。
下面来看最简单的Action与Func的定义:
Action a1 = () => { };Func<int> f1 = () => { return 1; };//必须写 return 1;Action与Func是泛型委托,最多支持16个入参变量 。下面代码为一个入参的定义,多参数以此类推 。
Action<int> a1 = (i) => { };Func<string,int> f1 = (str) => { return 1;//必须写 return 1; };委托的线程应用
委托的线程应用是委托的第二种用法,分为线程使用委托,和委托的异步应用两种 。
我们先看线程使用委托 。如下代码所示,一个无入参匿名Action和一个无入参匿名Func 。
Task taskAction = new Task(() => { });//无入参匿名ActiontaskAction.Start(); Task<int> taskFunc = new Task<int>(() => { return 1; });//无入参匿名FunctaskFunc.Start();int result= taskFunc.GetAwaiter().GetResult();//获取线程返回结果


推荐阅读