【发布时间】:2012-02-19 02:31:07
【问题描述】:
在为 SO-answer 生成示例数据时,我想到了这个问题。
我不喜欢通过 Tbl.Rows.Add 逐一添加 DataRows 的冗长方式,所以我创建了这个伪 LINQ 查询,它除了隐式添加行之外什么都不做:
Private Function GetData() As DataTable
Dim years = {"2010/2009", "2009/2008", "2008/2007", "2007/2006", "2006/2005", "2005/2004", "2004/2003"}
Dim tbl = New DataTable
tbl.Columns.Add(New DataColumn("Year"))
' adds DataRows to the DataTable, need Count to execute the query '
Dim c = (From y In years Select tbl.Rows.Add(y)).Count
Return tbl
End Function
如您所见,我根本不需要查询的结果,它的唯一目的是迭代并调用DataTable.Rows.Add。所以结果已经在 DataTable 本身中可用,查询不需要。
诚然,这个问题有点虚伪,因为使用 f.e. 不会有很大的不同。 ToList 通常查询的目的是返回一些东西。
但无论如何,当只关心执行而不重要结果时,执行 LINQ 查询的最便宜的方式(就内存消耗、执行时间而言)是什么?
编辑:好的,这个问题是一个快速的问题和先有鸡还是先有蛋的问题。我想将 20 行代码减少到一行,但注意到我需要某种数据源用于 LINQ 查询。因此我创建了数组。但此时我也可以简单地使用 for-each 循环来添加 DataRows。
结论:将 LINQ 查询用于它的用途:查询。那么这个问题是没有意义的,因为没有最便宜的方法,只有返回正确结果的方法。
【问题讨论】:
-
foreach不会产生更具可读性的代码吗?这看起来像是 因为我可以使用 LINQ 的情况。这也有点反 LINQ,因为它有副作用。 -
LINQ 不保证会发生任何副作用:例如,LINQ-to-objects 可以以
Count忽略任何Select投影的方式实现,因为它们不会改变元素的数量。因此,您依赖的是一种未记录的行为,这种行为(理论上)可能随时发生变化。 -
你的核心问题应该被回答,你不应该那样做。您正在尝试用投影代替动作。然后,您强制实现以强制执行您的副作用(预期的操作)。
-
+1 的答案是这个问题的灵感来源。
-
@Marc:是的,你是对的。不幸的是,这个例子没有我想象的那么好。首先,我通过简单地创建新行(
tbl.NewRow)、填充它们并最后将它们添加到 DataTable 来创建没有循环的 DataTable。所以我问自己这 20 行代码是否没有单行代码。因此我创建了那个数组。在这一点上,我也可以使用 for-each 。在创建 LINQ 查询之后,我错过了这一点。
标签: .net vb.net performance linq