2012-07-02 51 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