C#问题之委托详解(ActionFunc匿名方法Lambda表达式)
委托基础知识
C#使用一个类需要两个阶段,
定义类,告诉编译器由什么字段和方法组成,实例化这个类的对象
委托也需要这两个阶段
定义一个委托,告诉编译器这个委托指向哪个类型的方法,然后创建类的实例
delegate void Method(int x);
定义了一个委托名为Method,它可以指向哪些方法呢?
这个方法要带有一个int类型的参数,并且方法的返回值是void
定义委托需要使用delegate关键字,要定义方法的参数(可以没有)和返回值
当一个委托没有指向任何一个方法时,会出现异常
举例一:
delegate string Mathof();
static void Main(string[] args)
{
int x = 40;
Mathof mathof = x.ToString;//m指向了x中的ToString方法的引用,没有调用该方法
Console.WriteLine(x.ToString());
Console.WriteLine(mathof());
Console.ReadKey();
}
举例2:
delegate void Mathof();
static void Main(string[] args)
{
Mathof math = Method1;//指向Method1方法的引用
math(); //或者Trans(math)也能实现Method1方法
math = Method2; //重新指向Method2方法的引用
math(); //或者Trans(math)也能实现Method2方法
Console.ReadKey();
}
static void Method1() {
Console.WriteLine("Method1");
}
static void Method2()
{
Console.WriteLine("Meyhod2");
}
static void Trans(Mathof math)
{
math();
}
Action为系统预定义的委托,是一个有或没有参数,永远没有返回值的委托,类似于:##
Action delegate void Action();
Action delegate void Action(int exampe);
举例:
class Program
{
static void Main(string[] args)
{
Action a = Method;//a指向一个方法为无返回值,无参数的方法的引用
a();
Console.ReadKey();
}
static void Method() {
Console.WriteLine("Hello world!");
}
}
当Action要指向一个有参数的方法时,则需要:
Action<T,T...> a; //a指向一个方法为无返回值,int参数的方法的引用
举例:
static void Main(string[] args)
{
Action<int,string> a = Method;//a指向一个方法为无返回值,int参数以及string参数的引用
a(464,"Hello World");
Console.ReadKey();
}
static void Method(int value,string name) {
Console.WriteLine(value+name);
}
Func委托引用了一个带有一个返回值的方法,它可以传递0个或多至16个参数类型,一个返回值的方法。##
Func<T,T...Tresult> //前面是参数类型,最后一个是返回值类型
举例:
class Program
{
static void Main(string[] args)
{
// 参数 参数 返回值
Func f<int,string,int> = Method;
Console.WriteLine(f(1,"Hello World"));
Console.ReadKey();
}
static int Method(int value,string s) {
Console.WriteLine(value+s);
return value;
}
}
多播委托多播委托的返回值类型一般为void。多播委托包含一个逐个调用的委托集合,其中一个方法出现异常,整个迭代都会停止。##
举例:
static void Text1() {
Console.WriteLine("Text1");
}
static void Text2() {
Console.WriteLine("Text2");
}
static void Main(string[] args)
{
Action a = Text1;
a += Text2;//a委托添加Text2方法
a -= Text1;//a委托除Text1方法
a();
Console.ReadKey();
}
取得多播委托中的所有方法,举例:
static void Text1() {
Console.WriteLine("Text1");
}
static void Text2() {
Console.WriteLine("Text2");
}
static void Main(string[] args)
{
Action a = Text1;
a += Text2;//
Delegate[] delegates = a.GetInvocationList();
foreach (Delegate i in delegates)
{
i.DynamicInvoke();//如果方法中有参数,在括号里写入
}
Console.ReadKey();
}
匿名方法
举例:
static void Main(string[] args)
{
Func meth = delegate (int arg1, int arg2)
{
return arg1 + arg2;
};
int res=meth(5, 7);
Console.WriteLine(res);
Console.ReadKey();
}
Lambda表达式。
lambda表达式实际上是代替匿名方法。只要有委托参数类型的地方就可以使用Lambda表达式。
Lambda表达式可以访问外部的变量,一般不用,结果不但受到参数的控制,还受到外部变量的控制。
举例:
static void Main(string[] args)
{
//匿名方法
//Func<int,int,int> meth = delegate (int arg1, int arg2)
//{
// return arg1 + arg2;
//};
//int res=meth(5, 7);
//Console.WriteLine(res);
//Lambda表达式
Func<int,int,int> meth = (arg1, arg2) =>
{
return arg1 + arg2;
};
int res = meth(2, 3);
Console.WriteLine(res);
Console.ReadKey();
}
Lambda表达式只有一个参数的时候,括号可以省略,函数体语句只有一句的时候,可以省略大括号和return,需要返回值时,自动加上return
举例:
Func me = a => a + 1;//有返回值时,除了大括号可以省略,return也可以省略
int res = me(2);
Console.WriteLine(res);
Action ac = str => Console.WriteLine(str);
ac("Hello World");
Console.Readkey();