努力用LINQ理解Lambda表达式

时间:2015-02-02 10:55:28

标签: c# linq lambda

我对此非常陌生,我无法理解我在网上看到的例子。我一直在尝试使用lambda语句对列表进行排序,就像我在网上找到的示例代码一样:

public void Linq29()
{
string[] words = { "cherry", "apple", "blueberry" };

var sortedWords = words.OrderBy(word => word.Length);

Log.WriteLine("The sorted list of words (by length):");
foreach (var w in sortedWords)
{
    Log.WriteLine(w);
}

}

我已经阅读了很多关于它是如何工作的信息,但是我不能只关注“单词”如何开始引用单词列表中的项目。

任何人都可以用非常简单的术语帮助我这样做,这样我就可以开始理解它了。

感谢。

5 个答案:

答案 0 :(得分:3)

该行

var sortedWords = words.OrderBy(word => word.Length);

使用所谓的lambda表达式,这是一个与Linq分开的概念。可以使用单独的函数

实现相同的功能
public static int function(string word)
{
    return word.Length;
}

并按如下方式使用。

var sortedWords = words.OrderBy(function);

lambda表达式word => word.Length要短得多,并且内联定义了类似的函数。在这个公式中,word(在左侧)定义了参数的名称。

答案 1 :(得分:2)

  

我已经阅读了很多关于它是如何工作的信息,但是我不能理解这些词是怎么回事#'可以开始引用单词列表中的项目。

OrderBy是IEnumerable<T>的扩展方法,这是您的单词列表。

OrderBy可以枚举元素本身,因为它知道words类型为IEnumberable<T>

然而,OrderBy需要一个&#34; keySelector&#34;让它知道你想要订购什么。 keySelector是委托类型。这应该采取参数并返回一些东西。 (MSDN称之为&#34;从元素中提取密钥的函数。&#34;)

word => word.Length

word是参数,word.Length是方法体。

所以你要接受这个词,然后再回过头来。

答案 2 :(得分:1)

想想&#34;字&#34;作为参数,您将传递给将元素排序的函数。

您需要对序列的元素进行排序是什么?首先,您需要一个标准,为序列中的任何给定元素确定它是否应该在后续元素之前。通常你会通过一个函数定义它,因为一个函数可以接受任意数量的元素/参数和&#34; state&#34; / return&#34;一个单一的肯定/事物&#34;关于它收到的输入元素。在我们的例子中,一个sort函数在收到两个元素后,会在命令元素时说明1st是否应该在2nd之前。

在定义了这样的标准之后,您需要检查每个元素,并根据排序标准(如上所述)检查当前元素是否应该在下一个元素排序之前。

这就是框架为您提供接收函数的Sort方法的原因。它将为您循环遍历每个序列元素,并检查排序条件的结果,并在此基础上对元素进行排序。

答案 3 :(得分:1)

我打算用这个概念来帮助我首先让我的头围绕着lambdas。让我们看看lambda:

word => word.Length

这是(word) => word.Length的简写,而后者又是(word) => {return word.Length;}

的简写

对于具有类型推断的匿名函数,这个lambda反过来简单,因此下面只是伪代码:

delegate(var word) {return word.Length;}

编译器可以推断出var的类型,因此在你的例子中这是简写:

delegate(string word) {return word.Length;}

反过来又简写(输出类型也是不同的,所以这是特定于你的例子):

    static class [compilerInventMeAClassNamePlease] 
    {
       static int [compilerInventMeAMethodNamePlease] (string word) 
       {
          return word.Length;
       }
    }
...
    [a call to][compilerInventMeAMethodNamePlease]

这些类和方法实际上是由编译器完成的。

因此,lambda是一种内联创建匿名类/方法的方法,您没有给出名称并定义它。 =>左侧的所有内容都是签名。当你对它感到满意的时候,你可能会发现它更容易编写,至少最初是以长手形式编写的:

(string word, int multiply) => { return word.Length * multiply;  }

请注意lambda生成的类可能不是静态的,而是一个真实的实例类,它有自己的实例字段,这是由于一个叫做闭包的概念,当你对lambdas感到满意时,接下来要调查的是

答案 4 :(得分:1)

  

'word'如何开始引用单词列表中的项目

检查方法签名:

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector
)

所以它是IEnumerable<TSource>的扩展方法。它需要一个Func<TSource, TKey>类型的参数,它本身就是一个委托,这就是为什么你提供一个匿名函数作为参数:(word) => { word.Length; }。程序知道word与集合words的项目类型相同,因为wordTSource类型的参数,其类型与this IEnumerable<TSource> source相同{1}}方法OrderBy()来自。