C#编程指南 匿名函数 lambda表达式

时间:2021-05-06 19:15:29

匿名函数是一个“内联”语句或表达式,可在需要委托类型的任何地方使用。可以使用匿名函数来初始化命名委托,或传递命名委托(而不是命名委托类型)作为方法参数。

共有两种匿名函数:

1.Lambda表达式

2.匿名方法

C#委托

class Test
{
delegate void TestDelegate(string s);
static void M(string s)
{
Console.WriteLine(s);
}

static void Main(string[] args)
{
TestDelegate testDelA = new TestDelegate(M);
TestDelegate testDelB = delegate(string s) {Console.WriteLine(s); };
TestDelegate testDelC = (x) => { Console.WriteLine(x); };

testDelA("Hello. My name is M and I write lines.");
testDelB("That's nothing. I'm anonymous and ");
testDelC("I'm a famous author.");
}
}

Lambda表达式

"Lambda表达式"是一个匿名函数,它可以包含表达式语句,并且可用于创建委托或表达式树类型。

所有Lambda表达式都使用Lambda运算符=>,该运算符读为“goes to”。该Lambda运算符的左边是输入参数(如果有),右边则包含表达式或语句块。

=>运算符具有与赋值运算符(=)相同的优先级,并且是右结合运算符。

Lambda在基于方法的LINQ查询中用作标准查询运算方法(如Where)的参数。

使用基于方法的语法在Enumerable类中调用Where方法时,参数是委托类型System.Func(Of T,TResult)。使用Lambda表达式创建委托最为方便。

在is或as运算符的左侧不允许使用Lambda。

1.基本形式:

(input parameters) => expression

2.只有在Lambda有一个输入参数时,括号才是可选的;否则括号是必需的。两个或更多输入参数由括号中的逗号分隔:

(x,y) => x == y
3.有时,编译器难于或无法推断输入类型。如果出现这种情况,您可以按以下方式显式指定类型:

(int x,string s) => s.Length > x
4.使用空括号指定零个输入参数:

() => SomeMethod()

Lambda语句

Lambda语句与Lambda表达式类似,只是语句在大括号中:

(input parameters) => {statement;}

Lambda语句的主体可以包含任意数量的语句;但是,实际上通常不会多于两个或三个语句。

 

带有标准查询运算符的Lambda

许多标准查询运算符都具有输入参数,其类型是泛型委托的Func(Of T,TResult)系列的其中之一。Func(Of T,TResult)委托使用类型参数定义输入参数的数目和类型,以及委托的返回类型。

例如,假设有以下委托类型:

public delegate TResult Func<TArg0,TResult>(TArg0 arg0)

可以将委托实例化为Func<int,bool> myFunc,其中int是输入参数,bool是返回值。始终在最后一个类型参数中指定返回值。Func<int,string,bool>定义包含两个参数(int和string)且返回类型为bool的委托。

在调用下面的Func委托时,该委托将返回true或false以指定输入参数是否等于5:

Func<int,bool> myFunc = x => x == 5;
bool result = myFunc(4);

匿名方法

在2.0之前的C#版本中,声明委托的唯一方法是使用命名方法。C#2.0引入了匿名方法,而在C#3.0及更高版本中,Lambda表达式取代了匿名方法,作为编写内联代码的首选方式。有一种情况下,匿名方法提供了Lambda表达式中所没有的功能。您可使用匿名方法来忽略参数列表。这意味着匿名方法可以转换为具有各种签名的委托。这对于Lambda表达式来说是不可能的。

要将代码块传递为委托参数,创建匿名方法则是唯一的方法。

//例1
button1.Click += delegate(System.Object o, System.EventArgs e)
{ System.Windows.Forms.MessageBox.Show("Click!"); };
//例2
delegatevoid Del(int x);
Del d = delegate(int k) { /* ... */ };

下面的示例演示实例化委托的两种方法:

1.使委托与匿名方法关联。

2.使委托与命名方法(DoWork)关联。

delegate void Printer(string s);

class TestClass
{
static void Main()
{
//1.使委托与匿名方法关联.
Printer p = delegate(string j)
{
System.Console.WriteLine(j);
};
p("The delegate using the anonymous method is called.");

//2.使委托与命名方法 (DoWork) 关联。
p = new Printer(TestClass.DoWork);
p("The delegate using the named method is called.");
}

static void DoWork(string k)
{
System.Console.WriteLine(k);
}
}