C# 何时何地使用LINQ转换对象?

C# 何时何地使用LINQ转换对象?,c#,.net,vb.net,linq,C#,.net,Vb.net,Linq,在哪些情况下我应该使用LINQ来创建对象 显然,没有林克我什么都能做。那么LINQ在哪些操作中真正帮助我编写了更短的和/或更可读的 LINQ在以下几种情况下非常有用: 您希望使用类型化的“业务实体”,而不是数据表,以更自然地访问您的数据(并且还没有使用NHibernate或LLBLGenPro之类的工具) 您希望使用类似SQL的语法查询非关系数据(这在查询列表等时非常方便) 您不喜欢很多内联SQL或存储过程 当您开始对复杂数据类型进行复杂筛选时,LINQ将发挥作用。例如,如果给您一个人员对象列

在哪些情况下我应该使用LINQ来创建对象

显然,没有林克我什么都能做。那么LINQ在哪些操作中真正帮助我编写了更短的和/或更可读的


LINQ在以下几种情况下非常有用:

  • 您希望使用类型化的“业务实体”,而不是数据表,以更自然地访问您的数据(并且还没有使用NHibernate或LLBLGenPro之类的工具)
  • 您希望使用类似SQL的语法查询非关系数据(这在查询列表等时非常方便)
  • 您不喜欢很多内联SQL或存储过程

当您开始对复杂数据类型进行复杂筛选时,LINQ将发挥作用。例如,如果给您一个人员对象列表,您需要收集该列表中所有医生的列表。使用LINQ,您可以将以下代码压缩到单个LINQ语句中:

(伪代码)

(对不起,我的C#已经生锈了,类型检查语法可能不正确,但你明白了)


我发现LINQ对各地的物品都很有用。它解决的问题相当普遍:

  • 您有一些数据项的集合
  • 您需要另一个集合,由原始集合形成,但经过某种转换或过滤。这可能是排序、投影、应用谓词、分组等
我经常遇到这种情况。编程的很多领域基本上都涉及到将一个集合(或数据流)转换成另一个集合。在这些情况下,使用LINQ的代码几乎总是更短、更可读。我想指出,LINQ不应该被视为查询表达式的同义词——如果只需要一个运算符

我特别喜欢LINQtoObjects的原因之一是它非常通用——而LINQtoSQL很可能只涉及到您的数据层(或几乎成为数据层),LINQtoObjects适用于每一层以及所有类型的应用程序

举个例子,这里是我的MiniBench基准测试框架中的一行,它将
TestSuite
(基本上是一个命名的测试集合)转换为
ResultSite
(一个命名的结果集合):

然后,如果需要根据某个特定的“标准”结果缩放
resultSite

如果没有LINQ,编写这段代码并不难,但LINQ只是让代码更清晰,让您能够专注于真正的“逻辑”,而不是迭代循环和向列表添加结果等细节


即使LINQ本身不适用,一些主要为了LINQ而包含的特性(例如隐式类型的局部变量、lambda表达式、扩展方法)也非常有用。

我想到了答案几乎无处不在。一个更好的问题是什么时候不使用它。

编辑:在我回答之后,我看到一个变化,说“LINQ to Objects”。哦,好吧

如果通过LINQ我们引用System.LINQ中的所有新类型,以及新的编译器特性,那么它将有相当多的好处——它有效地将函数编程添加到这些语言中。(这是我见过几次的进展(虽然这主要是C#——VB在当前版本中受到限制)

一个明显的开始是,任何与列表处理相关的事情都变得非常容易。许多循环都可以消失。你会得到什么好处?你将开始以更声明的方式编程,这将导致更少的bug。当切换到这种风格时,事情开始“正常工作”。(我觉得LINQ查询语法不太有用,除非查询非常复杂,有很多中间值。在这些情况下,语法将解决所有问题,否则必须传递元组。)

接下来是语言支持(在C#和下一版本的VB中)for anonymous方法允许您以更短的方式编写更多的构造。例如,可以在启动异步回调的方法内部定义处理异步回调。在此处使用闭包将使您不必将状态绑定到不透明对象参数中,并在以后将其抛出

能够使用高阶函数会让你思考得更一般。因此,你会开始看到你可以在哪里简单地传递lambda并更整洁地解决问题。在这一点上,你会意识到只有使用泛型才能真正起作用。当然,这是一个2.0特性,但当你传入时,这种用法会更普遍g的作用是围绕着

在这一点上,你进入了收益递减的阶段。声明和使用func以及声明所有泛型类型参数(在C#和VB中)的成本相当高。编译器无法为你计算,因此你必须全部手动完成。这增加了大量的开销和摩擦,这限制了你的能力

那么,这都是“LINQ”吗?可能取决于市场营销。LINQ的推广使这种编程风格在C#中变得更加容易,而且所有LINQ都基于FP思想。

LINQ对于“滑坡”来说是非常好的。想想在许多常见的操作中都涉及到了什么:

  • 其中。只需编写一个foreach循环和一个“if”
  • 选择。创建一个空的目标类型列表,循环遍历原始类型,转换每个类型并将其添加到结果中
  • OrderBy。只需将其添加到列表并调用.Sort()。或实现气泡排序;)
  • 然后按(从order by PropertyA开始,然后按PropertyB开始)。难度相当大。自定义比较器和排序应该可以实现这一点
  • GroupBy-创建一个
    字典
    并循环浏览所有项目。如果没有键,则创建它,然后将项目添加到相应的列表中
在每一种情况下,程序
doctors = []
for person in people:
    if person is doctor:
        doctors.append(person)
doctors = from person in people where person.type() == doctor select person;
return new ResultSuite(name, 
    tests.Select(test => test.Run(input, expectedOutput)));
return new ResultSuite(name, 
    results.Select(x => x.ScaleToStandard(standard, mode)));