委托
什么是委托?
委托是类类型,也就是引用类型,能声明变量,创造实例。但委托是一种特殊的类,一般的类是用来反应现实事物的,而委托类只是用来包裹方法的,通过委托实例可以来间接调用这些包裹的方法。所以可以说委托就是一个或一组方法的封装器。
using System;
using System.Collections.Generic;
namespace ConsoleApp2
{internal class Program{static void Main(string[] args){//委托能包裹的方法,必须与委托的返回值、参数列表一致。如下就是void返回值、以及0个参数MyDele myDele11 = new MyDele(f1);myDele11.Invoke();//执行包裹着的方法,可以简化成myDele11();}static void f1() { Console.WriteLine("方法一"); }}delegate void MyDele();//委托声明
}
泛型委托
手动声明委托类型
namespace ConsoleApp2
{internal class Program{static void Main(string[] args){MyDele<int> myDele11 = new MyDele<int>(f1);//用int替换TmyDele11.Invoke(1,2);//执行包裹着的方法MyDele<double> myDele22 = new MyDele<double>(f2);//用int替换TmyDele22(1.21, 3.14159);//执行包裹着的方法}static int f1(int x,int y) { return x+y; }static double f2(double x,double y) { return x+y; }}}delegate T MyDele<T>(T a,T b);//泛型委托声明
}
实际上类库已经声明好了泛型委托,不用自己去声明。主要有两大类,有返回值的Func,以及无返回值的Action。
以下是使用action委托:
using System;
using System.Runtime.CompilerServices;namespace ConsoleApp2
{internal class Program{static void Main(string[] args){Action action11 = new Action(f11);//使用action委托封装无参方法Action<int, string> action22 = new Action<int, string>(f22);//使用action委托封装有参方法}static void f11() { Console.WriteLine("我是无参无返回值方法"); }static void f22(int a,string s) { Console.WriteLine($"我是#{a}号,{s}"); }}
}
以下是使用function委托:
using System;
namespace ConsoleApp2
{internal class Program{static void Main(string[] args){var func11 = new Func<int, int, int>(f1);//表示包裹一个为int返回值、2个int参数的方法}static int f1(int x,int y) { return x+y; }static double f2(double x,double y) { return x+y; }}}
}
Lambda表达式
lambda 是一种匿名方法、Inline方法(边声明边使用)。
把一个lambda表达式赋值给一个委托类型变量
代码实例:
using System;
namespace ConsoleApp3
{internal class Program{static void Main(string[] args){Func<int, int, int> func1 = new Func<int, int, int>((a, b) => { return a + b; });Console.WriteLine(func1(231,43));}}
}
代码详解:
首先里面的lambda表达式是(a, b) => { return a + b; },它处于原本该放方法名的地方,不难相出这个lambda表达式代表着一个方法,表示将int类型的a,b带入花括号中,而花括号代表着返回一个相加后的int值。
观察lambda表达式代表的方法,是匿名的,没有名字。执行到这的时候,是边声明就边使用
这段代码还可以简化成:
Func<int, int, int> func1 = (a, b) => { return a + b; };
把一个lambda表达式喂给一个委托类型参数
观察上述 Func<int, int, int> func1 = (a, b) => { return a + b; };,它可以将一个lambda表达式来直接实例一个泛型委托,当然具体实现上不是这么简单,但是可以以这种形式完成,那么就可以想到有一个泛型委托形参,我们可以用lambda表达式当成泛型委托实参。
可以用类比int类型,这个泛型委托形参,代表着可以传进去某一组方法(这里是指有2个T参数,1个T返回值),就像int形参,传入参数为像1,3,543这种整数。那个传进去的方法可以用lambda写出表示。
using System;
namespace ConsoleApp4
{internal class Program{static void Main(string[] args){FangFa<int>((int a, int b)=>{ return a * b; },100,200);//放入三个参数}//泛型方法中有3个参数,第一个参数类型是泛型委托static void FangFa<T>(Func<T,T,T>func,T x,T y){T result=func(x,y);//调用泛型委托中的方法,该方法自己在主函数中边声明,边调用Console.WriteLine(result);}}
}
FangFa<int>((int a, int b)=>{ return a * b; },100,200);
可以将里面的int省去,因为100,200明显是整数,也就是T是int整数。系统自己能推断出来。所以写int多余了,可以将此代码写成:
FangFa((a, b)=>{ return a * b; },100,200);