LINQ Lambda表达式 - LinQ教程

术语“Lambda表达式'是来自于”拉姆达“演算这又是施加用于定义功能的数学符号及其名称。 lambda表达式作为LINQ式的可执行部分转换的方式在运行时的逻辑,因此它可以传递到数据源方便。但是,lambda表达式不仅仅局限于查找应用LINQ而已。

这些表达式由下面的语法表示:

(输入参数) => 表达式或语句块

下面是lambda表达式的一个例子

y => y * y

上述表达式指定一个参数y和y的值的平方。然而,这是不可能的到这种形式来执行一个lambda表达式。在C#中的lambda表达式的例子如下所示。

C

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace lambdaexample
{
  class Program
  {
     delegate int del(int i);
     static void Main(string[] args)
     {
        del myDelegate = y => y * y;
        int j = myDelegate(5);
        Console.WriteLine(j);
        Console.ReadLine();
     }
  }
}

VB

Module Module1
  Private Delegate Function del(ByVal i As Integer) As Integer
  Sub Main(ByVal args As String())
     Dim myDelegate As del = Function(y) y * y
     Dim j As Integer = myDelegate(5)
     Console.WriteLine(j)
     Console.ReadLine()
  End Sub
End Module

当C#或VB的上述代码被编译和执行时,它产生了以下结果:

25

表达Lambda

如在lambda表达式的上面所示的语法表达是在右手侧,这些也被称为lambda表达式。

异步Lambdas

通过使用异步关键字结合异步处理创建lambda表达式被称为异步lambda表达式。下面是异步lambda的一个例子。

Func<Task<string>> getWordAsync = async() => “hello”;

Lambda的标准查询操作

查询运算符内的lambda表达通过在需要时相同的评估计算,并不断地作用于各输入序列中的元素,而不是整个序列。 开发人员允许Lambda表达式到自己的逻辑转换成标准查询操作.在下面的例子中,开发人员使用的“Where”运算符,通过利用lambda表达式的回收,从给出的列表中奇数值。

C

//Get the average of the odd Fibonacci numbers in the series... 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace lambdaexample
{
  class Program
  {     
     static void Main(string[] args)
     {
        int[] fibNum = { 1, 1, 2, 3, 5, 8, 13, 21, 34 };
        double averageValue = fibNum.Where(num => num % 2 == 1).Average();
        Console.WriteLine(averageValue);
        Console.ReadLine();
     }
  }
}

VB

Module Module1
  Sub Main()
     Dim fibNum As Integer() = {1, 1, 2, 3, 5, 8, 13, 21, 34}
     Dim averageValue As Double = fibNum.Where(Function(num) num Mod 2 = 1).Average()
     Console.WriteLine(averageValue)
     Console.ReadLine()
  End Sub
End Module

让我们编译和运行上面的程序,这将产生以下结果:

7.33333333333333

lambda类型推断

在C#中,类型推断方便地用于各种情况,而且也没有明确指定的类型。但是如果一个lambda表达式,类型推断将工作必须满足在已指定每种类型为编译器。让我们考虑下面的例子。

delegate int Transformer (int i);

这里,编译器采用的类型推理时的事实,x是一个整数,这是通过检查所述变压器的参数类型进行绘制。

Lambda表达式变量的作用域

有而这样的lambda表达式内发起变量的lambda表达式,使用变量的作用域并不意味着是可见的外部方法有一些规则。还有一个规则,一个捕获变量不是被垃圾回收,除非委托引用相同变得符合垃圾收集的行为。此外,还有禁止lambda表达式中的return语句导致返回封闭方法的规则。

这里有一个例子,以证明lambda表达式变量的作用域。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace lambdaexample
{
  class Program
  {
     delegate bool D();
     delegate bool D2(int i);

     class Test
     {
        D del;
        D2 del2;
        public void TestMethod(int input)
        {
           int j = 0;
           // Initialize the delegates with lambda expressions.
           // Note access to 2 outer variables.
           // del will be invoked within this method.
           del = () => { j = 10; return j > input; };

           // del2 will be invoked after TestMethod goes out of scope.
           del2 = (x) => { return x == j; };

           // Demonstrate value of j:            
           // The delegate has not been invoked yet.
           Console.WriteLine("j = {0}", j);        // Invoke the delegate.
           bool boolResult = del();

           Console.WriteLine("j = {0}. b = {1}", j, boolResult);
        }

        static void Main()
        {
           Test test = new Test();
           test.TestMethod(5);

           // Prove that del2 still has a copy of
           // local variable j from TestMethod.
           bool result = test.del2(10);

           Console.WriteLine(result);

           Console.ReadKey();
        }
     }
  }
}

让我们编译和运行上面的程序,这将产生以下结果:

j = 0
j = 10\. b = True
True

表达式树

Lambda表达式中使用表达式树结构广泛。表达式树放弃代码中的数据结构类似于树,其中每个节点本身是一样的方法调用的表达,或者可以是一个二进制运算如x<y,下面是lambda表达式的使用用于构造一个表达式树的一个例子。

LAMBDA语句

还有lambda表达式由两个或三个语句,但不仅在构造表达式树中。 return语句必须写在lambda语句。

lambda声明的语法

(params) => {statements}

lambda的声明示例

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace lambdaexample
{
  class Program
  {
     static void Main(string[] args)
     {
        int[] source = new[] { 3, 8, 4, 6, 1, 7, 9, 2, 4, 8 };

        foreach (int i in source.Where(
                 x =>
                 {
                    if (x <= 3)
                       return true;
                    else if (x >= 7)
                       return true;
                    return false;
                 }
                ))
        Console.WriteLine(i);
        Console.ReadLine();
     }
  }
}

让我们编译和运行上面的程序,这将产生以下结果:

3
8
1
7
9
2
8

lambda表达式被用作基于方法的LINQ查询参数,并决不允许有一个地方对操作的左侧像是或者就像匿名方法。 虽然,Lambda表达式何其相似匿名方法,这些根本不是限制被用来作为唯一表示。

使用lambda表达式要点要记住

  • lambda表达式可以返回一个值,并可以带有参数。
  • 参数可以用不同的方式使用lambda表达式无数的定义。
  • 如果在一个lambda表达式单独的语句,就没有必要花括号,而如果有多个语句,大括号以及返回值都是写必不可少的。
  • 随着lambda表达式,可以通过被称为闭合的特征来访问变量lambda表达式块的存在之外。利用闭合的应谨慎,以避免任何问题。
  • 这是不执行任何lambda表达式中的任何不安全的代码。
  • lambda表达式并不意味着使用操作符的左侧。