以下Lambda和Linq表达式是否相同?

时间:2009-06-05 22:26:41

标签: c# .net linq lambda

以下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!乔尔

3 个答案:

答案 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