2012-07-02 23 views
2

我有n个元素的一类,并返回元素的平方和的平方根的属性:C#的选择查询不修改外部变量

public double Length 
{ 
    get 
    { 
     double sum = 0.0; 
     Elements.Select(t => sum += t * t); 
     return Math.Sqrt(sum); 
    } 
} 

然而,这不工作 - 不管价值的元素,总和仍然是0.0。
为什么不能正常工作?

注:我已经实现了它的另一种方式,但我看明白了,为什么上面的代码不起作用

回答

7

LINQ使用deferred execution –的Select Method不执行用于立即所有元素拉姆达,但返回的IEnumerable<T>在被执行时,因为它是列举performes每个元件上的拉姆达。

另请注意,LINQ用于查询,而不是为每个元素执行一段代码。您应该编写代码,以便在lambda表达式中没有语句,只有没有副作用的表达式。您可以使用Sum Method当你试图计算总和:

public double Length 
{ 
    get 
    { 
     double sum = elements.Select(t => t * t).Sum(); 
     return Math.Sqrt(sum); 
    } 
} 

public double Length 
{ 
    get 
    { 
     double sum = elements.Sum(t => t * t); 
     return Math.Sqrt(sum); 
    } 
} 
+0

所以你说因为指定的代码没有对选定项目进行任何后续枚举,所以不会评估表达式,并且求和不会改变? – 3Pi

+1

是的,确切地说。而且您不应只枚举所选项目,以便执行lambda。 – dtb

3

延迟执行。

试试这个:

public double Length 
{ 
    get { return Math.Sqrt(Elements.Sum(t => t * t)); } 
} 

这里LINQ查询立即执行。

+0

这其实是我已经实现了解决方案,但没有回答究竟是什么了,使得它并不像我期待合作的其他方法。 – 3Pi

+1

我应该详细说明。 Select语句返回IEnumerable ,IEnumerable被迭代后创建。由于您从不遍历IEnumerable,查询从未执行。因此总和没有修改。 –

+1

@ 3Pi:它精确地回答了为什么你的其他方法不起作用:查找延期执行 – BrokenGlass