以下Lambda和Linq表达式在执行路径方面是否相同?我想我想知道Linq是否会以不同的方式运行,因为它会在确定枚举中是否有任何内容之前创建一个IEnumerable,而lambda表达式将在它找到的第一个数字上停止。
var x = valueToMatch
.Any(c => Char.IsDigit(c));
var y = (from c in valueToMatch
select c).Any(c => Char.IsDigit(c)); here
THX!乔尔
答案 0 :(得分:3)
它将以不同的方式运行,但不会以任何相当大的方式运行。如果使用MSIL Disassembler,即使启用了优化,第一个表达式和第二个表达式的输出也会略有不同。您也可以使用Reflector(更容易阅读)来查看它。
第二个版本基本上会通过以下内容传递每个元素:
[CompilerGenerated]
private static char <Match2>b__2(char c)
{
return c;
}
在执行Any(c =&gt; Char.IsDigit(c))表达式之前。所以确实存在差异 然而,我认为差异很小。 使用每种方法测试10,000个字符的循环超过10,000,000的列表,第一个在~125ms左右计时,而第二种方法需要大约185ms。
答案 1 :(得分:1)
它们大致相同。 编译器可能会优化选择,两者将100%完全相同。在任何情况下,Linq都是惰性评估的,因此在两种情况下,valueToMatch都将枚举完全相同的数量。
答案 2 :(得分:0)
对于查询表达式,这代表identity function:
from c in valueToMatch select c
这意味着表达式的结果将完全等于输入matchToValue
。因此,您提供的示例在语义上是等效的。
如果是非身份选择,例如:
from c in valueToMatch select c + ";"
创建IEnumerable<char>
,枚举时将使用valueToMatch
的内容并更改它们。
这个电话:
(from c in valueToMatch select c + ";").Any(c => Char.IsDigit(c))
枚举内部查询,直到找到匹配项。如您所见,无论源查询如何,在调用Any
之前它都不会运行。 IEnumerable<char>
实例表示运行查询的能力,而不是已经运行的查询。这个概念称为deferred execution。