什么';s是OrderBy中lambda表达式的点

本文关键字:lambda 表达式 OrderBy 什么 | 更新日期: 2023-09-27 18:27:15

我有一个字符串列表,我想对它们进行排序。

IEnumerable<String> strings = ...;
strings = strings.OrderBy(a => a);

我没有得到lambda表达式a=>a的点。首先,我想我可以像这样拔出一处房产并同时订购。

IEnumerable<Something> somethings = ...;
IEnumerable<String> strings = somethings.OrderBy(a => a.StringProperty);

但这并不能编译。所以我必须这样走。

IEnumerable<Something> somethings = ...;
IEnumerable<String> strings = somethings.Select(a
  => a.StringProperty).OrderBy(a => a);

那么,为什么我必须在OrderBy命令中使用lambda表达式呢?!

什么';s是OrderBy中lambda表达式的点

lambda表示"您想要订购的依据"。

如果你带了一组人,并在他们的生日前订购,你仍然有一组人——而不是一组生日;即

IEnumerable<Person> people = ...;
IEnumerable<Person> sorted = people.OrderBy(a => a.DateOfBirth);

因此,类似地,用StringProperty对一组Somethings进行排序仍然会产生一组Somethings:

IEnumerable<Something> somethings = ...;
IEnumerable<Something> sorted = somethings.OrderBy(a => a.StringProperty);

在某些(极少数)情况下,你的意思实际上是"按事物本身排序"。这通常只适用于像IEnumerable<string>IEnumerable<int>这样的东西,所以.OrderBy(x => x)的微小不便是微不足道的。如果这让你感到困扰,你可以写一个扩展方法来隐藏这个细节。

当您订购集合时,它不会更改其类型,因此

IEnumerable<Something> somethings = ...; 
var strings = somethings.OrderBy(a => a.StringProperty);

结果为IEnumerable<Something>,则必须选择属性以更改类型:

IEnumerable<String> strings = somethings
    .OrderBy(s => s.StringProperty)
    .Select(s => s.StringProperty);

那么,为什么强制我在OrderBy中使用lambda表达式呢命令

因为Enumerable.OrderBy是一个需要参数的方法。

因为你没有选择它,所以你是按它排序的。

试试这个:

Console.WriteLine(string.Join(", ",
    new[] { new { Int = 1 }, new { Int = 2 }, new { Int = 0 }
    .OrderBy(a => a.Int));

这将为您提供按Int属性排序的列表,而不仅仅是随机排序的!

这意味着您可以通过对象的任何属性进行排序,而不仅仅是对象本身。

.OrderBy(TSource, TKey)方法的结构对Source项和要排序的项都有要求。lambda表示"使用TKey订购TSource",或者在您的情况下,"使用订购a"

参数lambda在OrderBy中的用途是精确地告诉用于排序的标准。它接受一个正在排序的对象,并返回另一个将被排序的"东西"(无论是否相同类型),有点像从原始源中提取一个要排序的键。

你的第一个样本真的很琐碎,你的咆哮在某种程度上是合理的,因为如果你从一个字符串列表开始,你很可能想要精确地按这些字符串排序。这也让我想知道,为什么对于那些琐碎的情况,我们不能有一个无参数的OrderBy

对于第二个片段:

IEnumerable<Something> somethings = ...;
IEnumerable<Something> strings = somethings.OrderBy(a => a.StringProperty);

这是"排序标准"有意义的时候,因为您根据从对象派生的一些属性值对对象进行排序,而不仅仅是对对象本身(通常不可比较)。它不编译的原因是在第二个可枚举声明中,它应该是IEnumerable<Something>而不是IEnumerable<string>,因为排序将返回另一个与它接收到的类型完全相同的列表,但顺序不同,,而不管排序标准如何。

在第三个代码段中,您通过Select对字符串属性进行处理来解决这个问题,这有效地生成了一个字符串列表,但在这个过程中会丢失所有输入对象。lambda参数在这里或多或少是毫无意义和琐碎的,因为您从一个普通字符串开始,与第一个示例完全相同。

另一种使用方法是指定一些不同的排序标准,而不是为字符串指定琐碎的排序标准。假设你不想按字母顺序排序,而是按第三个字母排序:

IEnumerable<String> strings = ...;
strings = strings.OrderBy(a => a.Substring(2, 1));