C#3.0之Lambda表达式

随着编程语言的演进,我们可以看到一个非常明显的趋势:让计算机去理解程序员,而不是程序员去理解计算机。从C#3.0中Lambda表达式可以明显看出这一点来。

现在看个例子:

// 使用C# 2.0 中的匿名方法查找“内部包含Lambda子串的所有字符串”:

list.FindAll(
delegate ( string  s)  {
return s.Indexof(“Lambda”) > =0; }

);

// 使用C# 3.0 中的Lambda表达式查找“内部包含Lambda子串的所有字符串”:

list.FindAll(s
=> s.Indexof(“Lambda”)  >=   0 );

我们看到在Lambda表达式中用到了一个新的符号"=>"类似于数学上的"推导出",我们在这里简单地称它为"推出"。上面的意思就是由s推出s里面包含字符串"Lambda"的字符串。至于s的类型则由编译器推导得出。这种表现形式比较符合人的思维模式。我们在数学上经常会用到由什么推出什么,听起来很自然。Lambda表达式不是微软首创,这个是学术界研究的成果,但是微软却把它第一个引入到了编程语言中。

下面看一下Lambda的格式:

/*(参数列表)=>表达式或者语句块
可以有多个参数,一个参数,或者无参数。参数类型可以隐式或者显式。
*/


// 例如:

(x, y) 
=>  x  *  y                              // 多参数,隐式类型=> 表达式
=>  x  *   10                                 // 单参数, 隐式类型=>表达式
=>   return x * 10; }                // 单参数,隐式类型=>语句块
( int  x)  =>  x  *   10                        //  单参数,显式类型=>表达式
( int  x)  =>   return x * 10; }       //  单参数,显式类型=>语句块
()  =>  Console.WriteLine()     // 无参数

我们可以看出Lambda表达式非常的灵活。参数类型都可以省略,有编译器去推导。而Lambda表达式的实质是什么呢?用ILDasm打开一个程序集看一下知道,其实还是匿名方法。只不过这些工作由编译器替你做了。

下面用几个例子说明一下编译器做的工作:

// 就拿list.FindAll( s=>s.Indexof(“abc”) > 0 );这句来说,看看编译器在背后生成了哪些东西

delegate   bool  MyDelegate1( string  s);

MyDelegate md1
= new  MyDelegate(XXXXX);    // XXXXX为下面方法的名字
list.FindAll(md1);

public   static   bool  XXXXX ( string  s)                    // XXXXX是方法的名字
{
       
return  s=>s.Indexof(“abc”) > 0;
}



/*这种写法是不是很熟悉,没错这就是在C#1.0中的写法,别管是C#2.0中的匿名方法还是
C#3.0中的Lambda表达式都会被编译器转化成这种形式
*/

我们再来看一下Lambda的简单举例:

delegate   int  Delegate1( int  a, int  b);
delegate   double  Delegate2( double  a, double  b);
delegate   string  Delegate3( string  s1, string  s2(;

public   class  LambdaExpression
{
     
public static void  DoSomething(Delegate1 d1){....}
}


// 我们就可以用下面的方法调用DoSomething

LambdaExpression.DoSomething((a,b)
=> a + b);       // 这里a,b和‘+’都可以换成别的变量名称或者其他操作符

/*现在我们可以推断出a,b的类型都为int,因为DoSomething的参数为Delegate1,而Delegate1的要求方
法的参数为int,所以很自然的推导出a,b为int类型
*/


// 如果我们这样写DoSomething方法

public   static   void   DoSomething(Delegate3 d3) {....}

// 然后这样调用

LambdaExpression.DoSomething((s1,s2)
=> s1 + s2);

// 很明显s1,和s2将被推导出为string类型 

//至于编译器在背后做了那些更细致的工作,我们上面已经说过了,这里不再细说  

Lambda表达式L可以被转换为委托类型D,需要满足以下条件:
• L和D拥有相同的参数个数。
• L的参数类型要与D的参数类型相同。注意隐式类型要参与类型辨析。
• D的返回类型与L相同,无论L是表达式,还是语句块。

 只要满足了上述条件,在可以使用委托表达的地方就可以使用Lambda表达式

我们看到其实Lambda表达式只是对匿名方法的换一种形式表达,但是带来的意义却不只是这些,随着越来越多的使用Lambda表达式你就会越来越觉得原来的那种匿名方法写法很笨,你就会不愿意再去使用那种方法。就好像当人们习惯了面向对象语言给我们带来的编程方便时,而没有人在想去用C语言写出面向对象的程序一样。

你可能感兴趣的:(编程,String,C#,语言,lambda,编译器)