匿名方法是为了简化委托的实现,方便调用委托方法而出现的,同时,匿名方法也是学好lambda表达式的基础。在委托调用的方法中,如果方法只被调用一次,这个时候我们就没有必要创建具名方法,从而用匿名方法更为方便。
下面一段代码是声明并使用了一个名称为Add20的方法(和之前的写法一样)
namespace demo1_0726
{
public delegate int OtherDel(int n);//声明委托
internal class Program
{
public static int Add20(int x)
{
return x + 20;
}
static void Main(string[] args)
{
OtherDel otherDel = new OtherDel(Add20);
Console.WriteLine("{0}", otherDel(5));
Console.WriteLine("{0}", otherDel(6));
Console.ReadKey();
}
}
}
下面的一段代码使用了匿名方法来替代Add20
namespace demo2_0726
{
public delegate int OtherDel(int n);//声明委托
internal class Program
{
static void Main(string[] args)
{
OtherDel otherDel = delegate (int x)
{
return x + 20;
};
Console.WriteLine("{0}", otherDel(5));
Console.WriteLine("{0}", otherDel(6));
Console.ReadKey();
}
}
}
可以在如下地方使用匿名方法
(1)声明委托变量时作为初始化表达式
(2)组合委托时在赋值语句的右边
(3)为委托增加事件时在赋值语句的右边
匿名方法表达式的语法包含如下部分:
//delegate类型关键字
//参数列表,如果语句块没有使用任何参数则可以省略
//语句块,包含了匿名方法的代码
//关键字( 参数列表) { 语句块 }
delegate (Parameters) {ImplementationCode}
匿名方法不会显示声明返回值。如果委托有void类型的返回值,匿名方法就不能有返回值。
//这里委托类型的返回类型是整形
delegate int OtherDel(int InParam);
static void Main()
{
OtherDel del=delegate(int x)
{
return x+20;//返回一个整型值
};
......
}
除了数组参数,匿名方法的参数列表必须在以下3方面与委托匹配:
参数数量;参数类型及位置;修饰符
以下情况,我们可以使圆括号为空或省略圆括号来简化匿名方法的参数列表(两项同时成立)
1 委托的参数列表不包含任何out参数
2 匿名方法不使用任何参数
举例
namespace demo2_0726
{
public delegate void OtherDel(int n);//声明委托
internal class Program
{
static void Main(string[] args)
{
Program program = new Program();
//OtherDel otherDel = delegate (int n)//可以写全
OtherDel otherDel = delegate //也可以省略括号
{
program.sum();
program.subtract();
};
otherDel(5);
Console.ReadKey();
}
void sum()
{
int n = 4;
n += 3;
}
void subtract()
{
int n = 4;
n -= 2;
}
}
}
如果声明委托的参数列表包含了params参数,那么params关键字在匿名方法的参数列表中就会被省略:
delegate void SomeDel(int X,params int[] Y)//在委托声明中使用params关键字
SomeDel mDel=delegate(int X, int[] Y)//在匹配的匿名方法中省略关键字
{
...
};
1 参数以及声明在匿名方法内部的局部变量的作用域限制在实现方法的主体之内.
2 与委托的具名方法不同,匿名方法可以访问它们外围作用域的局部变量和环境,方法中的代码可以访问外围变量并且输出它的值。
C#2.0引入了匿名方法,C#3.0引入了Lambda表达式,匿名方法演变成Lambda表达式,在使用中我们更希望使用Lambda表达式来替代匿名方法。
1 删除delegate关键字
2 在参数列表和匿名方法主体之间放lambda运算符=>。lambda运算符读作goes to
Mydel del=delegate(int x) {return x+1;};//匿名方法
Mydel le1= (int x)=>{return x+1;};//Lambda表达式
(1) 编译器可以从委托的声明中知道委托参数的类型,因此Lambda表达式允许我们省略类型参数。
带有类型的参数列表称为显示类型
省略类型的参数列表称为隐式类型
(2)如果只有一个隐式类型参数,我们可以省略周围的括号。
(3)Lambda表达式允许表达式的主体是语句块或者表达式。如果语句块包含了一个返回语句,我们可以将语句块替换为return关键字后的表达式(即去掉关键字return)。
Mydel del=delegate(int x) {return x+1;};//匿名方法
Mydel le1= (int x)=>{return x+1;};//Lambda表达式
Mydel le1= (x)=>{return x+1;};//省略类型的Lambda表达式
Mydel le1= x =>{return x+1;};//省略隐式类型周围的括号的Lambda表达式
Mydel le1= x => x+1 ;//去掉关键字return的Lambda表达式
(1) Lambda表达式参数列表中的参数必须在参数数量、类型和位置上与委托相匹配;
(2) 表达式的参数列表中的参数不一定需要包含类型(隐式类型),除非委托有ref或out参数–此时必须注明类型(显示类型)
(3) 如果只有一个隐式类型参数并且是隐式类型的,我们可以省略周围的括号。,否则必须有括号
(4) 如果没有参数,必须使用一组空的圆括号。