委托 delegate关键字,可以实现将函数作为参数传递
1、基本用法
委托是一个数据类型,与类同等级,用于指向某一个方法,然后通过委托来调用该方法
static delegate int delegateAdd(int a,int b);//创建一个返回值int,两个参数都是int的委托 class wt{ //先创建两个示例函数,返回值和参数类型与委托相同,才能传递给委托.为方便演示,暂时方法设置成static public static int add1(int a,int b){ return a+b; } public static int add2(int a,int b){ return a+b+10; } static void Main(string[] args){ delegateAdd a = new delegateAdd(add1);//实例化一个委托,将add方法赋给委托,也可以delegateAdd a =add1;简写 delegateAdd(1,2);//等同于调用add1,返回3 delegateAdd+=add2;//可以用+=和-=操作委托当中包含的方法,委托可以看做一个方法的集合 delegateAdd(1,2);//调用add1和add2,委托的返回值为最后一个方法的返回值,此处为13 } }
2、Action和Func
系统本身有两个定义好的委托类型,其中Action是无返回值(void)类型方法,Func有返回值
class wt{ public static void say(string s){//参数string,无返回值 Console.WriteLine(s); } public static string add(int a,int b){//参数两个int,返回值string int c=a+b; Console,WriteLine(c); return c.toString(); } static static void main(string[] args){ Action<string> say1 = say;//Action示例,尖括号内是参数类型列表,实例化一个无返回值委托实例 say1("Hello World");//输出Hello World Func<int,int,string> add1 = add;//Func示例,尖括号里前面是参数列表,最后一个是返回值类型,实例化一个有返回值委托实例 add1(1,2);//输出3,返回字符串类型"3" } }
3、通过利用实例,将方法名作为参数的实现
class wt{ public void say(string s){ Console.WriteLine("我想说:"+s); } public void eat(string s){ Console.WriteLine("我吃了:"+s); } public void dosth(Action<string> act,string c){ act(c); } static void Main(string[] args){ wt wt1 = new wt(); wt.dosth(wt.say,"你好"); wt.dosth(wt.eat,"苹果"); } }
4、使用匿名函数作为方法的参数
基本格式 方法名( delegate (参数列表){方法体} );
class wt{ public void dosth(Action<string> act,string c){ act(c); } public string dosth_2(Func<int,int,string> act,int a,int b){ act(c); } static void Main(string[] args){ wt wt1 = new wt(); //以下为使用delegate构造匿名函数方法 wt.dosth(delegate (string s){Console.WriteLine("我想说:"+s);},"你好"); wt.dosth(delegate (string s){Console.WriteLine("我吃了:"+s);},"苹果"); wt.dosth_2(delegate (int a,int b){ int c = a+b; return c.toString(); },1,2); } }
5、匿名函数的更简单写法,lambda表达式
基本格式 方法名( (参数列表) => {方法体} );
class wt{ public void dosth(Action<string> act,string c){ act(c); } public string dosth_2(Func<int,int,string> act,int a,int b){ act(c); } static void Main(string[] args){ wt wt1 = new wt(); //以下为使用lambda表达式构造匿名函数方法 wt.dosth((string s)=>{Console.WriteLine("我想说:"+s);},"你好"); wt.dosth((string s)=>{Console.WriteLine("我吃了:"+s);},"苹果"); wt.dosth_2((int a,int b)=>{ int c = a+b; return c.toString(); },1,2); } }
6、使用委托构造事件
可以类比一些图形界面编程中的监听,当执行某操作时触发,并执行某一操作
下面以Dog对象为例,有run方法,有v速度属性,事件设置为当狗在跑的时候触发,进行广播速度值
public class Dog{ public int v; public event Action onRun;//event关键字定义事件,无参数直接用Action不加尖括号 public Dog(){//初始化v v=10; } public void run(){ Console.WriteLine("狗在跑"); onRun(); } } class wt{ static void Main(string[] args){ Dog dg=new Dog(); dg.onRun += (()=>{Console.WriteLine("速度是:"+dg.v);}); dg.run(); //输出结果: //狗在跑 //速度是:10 } } //如果需要对事件进行删除,那么可以不使用匿名函数