当前位置: 首页 > 编程语言 > C# > 正文

C# 3.0特性之Lambda表达式

时间:2010-06-13 SpadeQ

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 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  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了。。