LINQ适用于哪些问题域?


12

每次我在C#的Stack Overflow上看到一个问题时,都会看到至少一个或两个答案可以解决LINQ问题。通常,声誉很高的人似乎像专家一样使用LINQ。

所以我的问题是,LINQ应该用于哪个问题域?

还要注意:是否有避免使用的目的?数据集的大小是否会影响LINQ查询的性能?




1
LINQ用于查询对象图。它是语言集成查询-它允许您查询和操作集合。
Oded

1
它可能是因为看台上关闭的问题,有可能是一个很好的问题潜伏在那里有什么问题LINQ是一个很好的适合不过
JK。

1
Linq是声明性的。您无需指定“完成方式”即可声明所需的“内容”。对于linq,这意味着您可以使用查询来声明所需的内容。对于某些问题,声明性代码可以更短并且更易于理解。
mike30

Answers:


16

LINQ的主要目的是允许对数据序列进行纯函数式的查询和转换(您会注意到,所有LINQ扩展都采用Func委托,而不采用Action委托)。因此,最不适合LINQ的循环的最常见情况是所有与非纯功能副作用有关的情况,例如

foreach(var x in list) Console.WriteLine(x);

为了更好地使用LINQ,只需练习使用它即可。

每次您要编写一个forforeach循环以对集合执行某项操作时,请停止操作,考虑一下它是否适合LINQ(即,它不仅对元素执行动作/副作用),如果这样做,则迫使您自己编写它使用LINQ。

您也可以先编写该foreach版本,然后再重写为LINQ版本。

就像svick指出的那样,LINQ应该使程序更具可读性。通常它擅长于此,因为它倾向于强调代码的目的而不是机制。但是,如果您发现无法使查询比简单的循环更具可读性,请随时坚持使用该循环。

如果您需要练习,大多数函数式编程练习都可以很好地映射到LINQ,例如99个问题(尤其是前20 个问题)或euler项目


我现在可能必须删除此问题。主持人评论说它不适合该社区。如果您有其他意见,请告诉我。
user1816120 2013年

1
我要补充一点,如果将其重写为LINQ,并且原始文件仍更具可读性,请保留原始文件并删除LINQ版本。有时,LINQ只是不添加任何内容。
svick

@svick理论上是的,虽然我不确定我能想到任何示例;)
jk。

1
@jk。例如,ReSharper有时会提供使用将我的循环转换为LINQ的功能Aggregate()。我认为大多数时候,循环更具可读性。
svick

大概@svick你所习惯的,虽然我承认骨料是折叠一个笨拙的名称的问题
JK。

1

要回答这个已编辑的问题:简而言之,每当您必须实现“查询”功能时(这就是LINQ中的Q所代表的),使用LINQ是有益的。定义确切的域很困难,但是它极大地简化了与从集合中提取和操作数据相关的各种任务。

简单地说,该语言(或更确切地说是各种LINQ实现器)直接引入了许多查询功能,因此,诸如聚合,排序,分组,过滤,投影,联接(还有更多)之类的事情都可以处理。您。基于LINQ的解决方案通常比您“手工”实现它们的时间要短得多,并且也可以更好地传达其意图。

一个通常有助于传达LINQ功能的简单示例是显示按扩展名分组的目录的内容。在您的脑海中执行一个典型的命令式实施-一开始就会有很多实施细节。也许我们将使用Dictionary<String, List<String>>扩展名来索引文件。当然,我们将必须检查键是否已存在,实例化列表,将其添加到列表等。它可能类似于:

Dictionary<string, List<string>> fileGroups = new Dictionary<string, List<string>>();

foreach (string file in Directory.GetFiles(Environment.CurrentDirectory))
{
    string extension = Path.GetExtension(file).ToLower();

    if (!fileGroups.ContainsKey(extension))
    {
        fileGroups[extension] = new List<string>();
    }

    fileGroups[extension].Add(file);
}

考虑等效于LINQ:

var query = from file in Directory.GetFiles(Environment.CurrentDirectory)
            group file by Path.GetExtension(file).ToLower();

注意,查询本身只有两行,当然比我们想出的任何命令式解决方案都要短。它也很可读。信噪比高于第一种解决方案。对于LINQ的新手,您将输出该查询的结果,如下所示:

foreach (var fileGroup in query)
{
    Console.WriteLine(String.Format("*** Files with extension: {0}", group.Key));

    foreach (string file in fileGroup)
    {
        Console.WriteLine(file);
    }
}

对于更复杂的示例,差异通常会变得更大(例如,考虑简单地按多个字段进行分组)。因此,总而言之,LINQ以通常更短,更具描述性的方式解决了许多“日常”数据查询问题。这是必须学习语法和技术的轻度代价,但是其好处远大于缺点。


您是否将地图或折叠分类为“查询”?我不是真的,但是我想我可能会看到它。.我通常认为是由于计算而不是“查询”而产生的汇总
Jimmy Hoffa 2013年

@JimmyHoffa我主要是指将计算应用到基础集合,而不一定是计算本身。但是在我的类比中可能存在一些漏洞,这只是为了说明而不是100%正确。
丹尼尔·B

@JimmyHoffa没有,但我不知道是否有一个查询是先从什么严格的定义
JK。

0

随着时间的推移,已经针对各种类型的数据源开发了不同的语言,例如用于关系数据库的SQL和用于XML的XQuery。因此,开发人员必须为他们必须支持的每种数据源或数据格式学习一种新的查询语言。LINQ通过提供用于处理各种数据源和格式的数据的一致模型来简化这种情况。在LINQ查询中,您始终在使用对象。有关更多信息,请访问http://msdn.microsoft.com/zh-cn/library/bb397906.aspx


确切地说,LINQ是用于处理集合的抽象API。一些重要的好处:使用C#,您将获得STATIC!验证您的查询和转换
AndreasScheinert
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.