【发布时间】:2010-10-09 01:57:37
【问题描述】:
在哪些情况下我应该使用 LINQ to Objects?
显然我可以在没有 LINQ 的情况下做任何事情。那么在哪些操作中 LINQ 真正帮助我编写更短和/或更具可读性?
【问题讨论】:
在哪些情况下我应该使用 LINQ to Objects?
显然我可以在没有 LINQ 的情况下做任何事情。那么在哪些操作中 LINQ 真正帮助我编写更短和/或更具可读性?
【问题讨论】:
我发现 LINQ to Objects 在所有地方都很有用。它解决的问题很笼统:
这是我经常遇到的情况。有很多编程领域基本上涉及将一个集合(或数据流)转换为另一个。在这些情况下,使用 LINQ 的代码几乎总是更短且更易读。我想指出,LINQ 不应被视为查询表达式的同义词——如果只需要一个运算符,the normal "dot notation" (using extension methods) can often be shorter and more readable。
我特别喜欢 LINQ to Objects 的原因之一是它如此通用 - 而 LINQ to SQL 可能只涉及您的数据层(或几乎成为数据层) , LINQ to Objects 适用于每一层,适用于各种应用程序。
举个例子,这是我的 MiniBench 基准测试框架中的一行代码,将 TestSuite(基本上是一个命名的测试集合)转换为 ResultSuite(一个命名的结果集合):
return new ResultSuite(name,
tests.Select(test => test.Run(input, expectedOutput)));
如果ResultSuite 需要针对某些特定的“标准”结果进行缩放:
return new ResultSuite(name,
results.Select(x => x.ScaleToStandard(standard, mode)));
如果没有 LINQ,编写此代码不会困难,但 LINQ 只是让它更清晰,让您专注于真正的“逻辑”,而不是迭代循环和添加结果的细节到列表等。
即使 LINQ 本身不适用,为了 LINQ 而主要包含的一些功能(例如,隐式类型的局部变量、lambda 表达式、扩展方法)也可能非常有用。
【讨论】:
答案几乎无处不在浮现在脑海中。一个更好的问题是何时不使用它。
【讨论】:
LINQ 非常适合“滑坡”。想一想许多常见操作中涉及的内容:
Dictionary<key, List<value>> 并遍历所有项目。如果不存在密钥,请创建它,然后将项目添加到适当的列表中。 在每种情况下,过程方式都比 LINQ 方式需要更多的代码。在“如果”的情况下,它多出几行;在 GroupBy 或 OrderBy/ThenBy 的情况下,它更多。
现在采取一个非常常见的场景,将它们组合在一起。你突然看到了一个 10-20 行的方法,它可以在 LINQ 中用 3-4 行来解决。并且保证 LINQ 版本更易于阅读(一旦您熟悉 LINQ)。
那么你什么时候使用 LINQ?我的回答:每当你看到“foreach” :)
【讨论】:
LINQ 在一些场景中非常有用:
【讨论】:
当您开始对复杂数据类型进行复杂过滤时,LINQ 就会发挥作用。例如,如果给您一个 People 对象列表,并且您需要收集该列表中所有医生的列表。使用 LINQ,您可以将以下代码压缩为单个 LINQ 语句:
(伪代码)
doctors = []
for person in people:
if person is doctor:
doctors.append(person)
(对不起,我的 C# 生锈了,类型检查语法可能不正确,但你明白了)
doctors = from person in people where person.type() == doctor select person;
【讨论】:
编辑:在我回答后,我看到一个更改为“LINQ to Objects”。那好吧。
如果我们通过 LINQ 引用 System.Linq 中的所有新类型,以及新的编译器功能,那么它将有很多好处——它有效地将函数式编程添加到这些语言中。 (这是我见过几次的进展(虽然这主要是 C# -- VB 在当前版本中受到限制)。
显而易见的开始是任何与列表处理相关的事情都变得非常容易。很多循环可以消失。你得到什么好处?您将开始更多地以声明方式进行编程,这将导致更少的错误。切换到这种风格时,事情开始“正常工作”。 (我觉得 LINQ 查询语法不太有用,除非查询非常复杂,有很多中间值。在这些情况下,语法将解决所有问题,否则您必须传递元组。)
接下来,匿名方法的语言支持(在 C# 和下一版本的 VB 中)允许您以更短的方式编写更多的构造。例如,处理异步回调可以在启动它的方法中定义。在这里使用闭包将导致您不必将状态捆绑到一个不透明的对象参数中并在以后将其投射出来。
能够使用高阶函数让您的思维更加通用。所以你会开始看到你可以在哪里简单地传递一个 lambda 并更简洁地解决问题。此时,您会意识到只有使用泛型才能真正发挥作用。当然,这是 2.0 的一个特性,但在传递函数时使用更为普遍。
在那里,您会进入收益递减点。声明和使用 func 以及声明所有泛型类型参数(在 C# 和 VB 中)的成本相当高。编译器不会为您解决问题,因此您必须手动完成所有操作。这会增加大量开销和摩擦,从而限制了您可以走多远。
那么,这就是“LINQ”吗?也许取决于营销。 LINQ 的推动使这种风格的 C# 编程变得更加容易,并且所有 LINQ 都基于 FP 思想。
【讨论】: