C# 3.0特性之Lambda表达式

源地址 http://www.cnblogs.com/SpadeQ/articles/1246226.html



C# 3.0特性之Lambda表达式


Attention: 本文内容包括示例来源均参考自Joseph C. Rattz, Jr.的Pro Linq一书。

Lambda表达式是MS在C# 3.0中引入的。Lambda表达式最早可见于LISP语言,美国数学家Alonzo Church在1936年将其概念化。这种表达式为描述算法提供了一种简便的手段。

在引入Lambda表达式之前,我们先看一看在这之前,将一个算法作为参数传递给一个方法是如何做到的。

使用命名方法(Named Methods)

在C# 2.0之前,可以使用委托(delegate)来完成这项工作。比如考虑这样一个应用,对数组元素按照一定的规则进行过滤,对于通用模块,可以写成下面的样子:

复制代码
public   class  Common
{
    
public delegate bool IntFilter(int i); 

    
public static int[] FilterArrayOfInt(int[] ints,IntFilter filter)
    
{
        ArrayList aList 
= new ArrayList();
        
foreach (int i in ints)
        
{
            
if (filter(i))
            
{
                aList.Add(i);
            }

        }
 

        
return ((int[]) aList.ToArray(typeof (int)));
    }

}
 
复制代码

然后搞算法的人就把过滤算法写成函数,比如下面的这样: 

复制代码
public   class  Application
{
    
public static bool IsOdd(int i)
    
{
        
return ((i & 1== 1);
    }

}
 
复制代码

这个IsOdd()方法,就是描述算法的named method。在实际的调用过程中,caller调用的是Common类的FilterArrayOfInt()方法,该方法的第二个参数,就是一个过滤器算法的委托(函数指针)。所有的过滤器算法必须是具有相同的参数和返回值类型。在调用FilterArrayOfInt()方法的时候,同时把描述算法的IsOdd()作为参数,代入委托,这样一个事件就搞定了。 

复制代码
static   void  Main( string [] args)
{
    
int[] nums = {12345678910};
    
int[] oddNums = Common.FilterArrayOfInt(nums, Application.IsOdd); 

    
foreach (int i in oddNums)
    
{
        Console.WriteLine(i);
    }

}
 
复制代码

结果当然是1、3、5、7、9。算法的实现者可以写出各种不同的filter,如此代入即可。

使用匿名方法(Anonymous Methods)

在C# 2.0中,引入了匿名方法,可以将代码内联来替换委托。上面的示例中Main()方法里的oddNums赋值可以改写如下:

int [] oddNums  =  Common.FilterArrayOfInt(nums,  delegate ( int  i)  return ((i & 1== 1); } );

在委托参数的地方可以简单地用这种内联的形式,由于没有定义一个确定名称的方法,就称作匿名方法。对于不怎么需要复用的代码,这种手段可以极大简化程序结构,但降低了可读性。对于比较复杂的函数体就很suck了。。

使用Lambda表达式

Lambda表达式的一般形式,是由一组由逗号分隔的参数列表,跟着一个lambda操作符,再跟着一个表达式或者语句块。多个输入参数的情况下需要用括号来包围。在C#中,lambda操作符是=>,因此,在C#中的lambda表达式应该是这个样子的: 

复制代码
(param1, param2, …paramN)  =>
{
statement1;
statement2;

statementN;
return(lambda_expression_return_type);
}
 

复制代码

再回过头看delegate的部分,一个delegate实际上就是指定了输入的参数格式以及返回值的格式,那么在lambda表达式中,就对应着=>左边的那一坨以及语句体里return的那个东东。在前面的例子中,输入是一个int型数据,返回一个bool量,比如: 

x => x.Length > 0  

这个表达式可以读作“x goes to x.Length >0”,或者“输入x,返回x.Length>0”。下面的lambda表达式可以返回输入参数的长度: 

s => s.Length

那么delegate就应该指定返回int型值。对于多个输入变量的,比如:

(x,y)  =>  x == y

再复杂一点的: 

复制代码
(x, y)  =>
{
if (x > y)
return (x);
else
return (y);
}
复制代码

好,下面我们来改造前面的那个例子,算法设计者所设计的lambda表达式必须满足委托的声明:  

delegate   bool  IntFilter( int  i);

则可以将oddNums的赋值写成这样: 

int [] oddNums  =  Common.FilterArrayOfInt(nums, i  =>  ((i  &   1 ==   1 ));

结果当然也会和前面完全一样。

小结

这篇文章仅仅是对lambda表达式的用法做一个简单的概要描述。对于那种经常需要复用的算法段,使用named method是最正统也是最合理的,匿名方法以及lambda表达式更加适合于那种一次性算法。说到这里大家应该很明白这东西的使用范畴了,对,那就是linq!在linq的查询操作中,几乎所有的算法都是不怎么复用的,如果为每个查询都写一个命名方法,其效率实在惨不忍睹,而lambda表达式正是为此应运而生的。又或者说,几乎所有的.net 3.5新语言特性都是为了linq服务的。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值