2011-10-20 71 views
10

有沒有更好的方式來使用LINQ來完成這些任務?有沒有辦法在LINQ中設置值?

IEnumerable<SideBarUnit> sulist1 = newlist.Where(c => c.StatusID == EmergencyCV.ID); 
foreach (SideBarUnit su in sulist1) su.color = "Red"; 
+1

[LINQ等效的foreach爲IEnumerable的(http://stackoverflow.com/questions/200574/linq-equivalent-of-foreach-for-ienumerablet) –

回答

8

你可以做這樣的事情,因爲其他的答案在這裏指出,但你不再那麼使用LINQ

Eric Lippert寫道an excellent blog post about this very subject,我強烈建議你閱讀。下面是摘錄:

哲學反對提供這樣的方法,有兩個原因。

第一個原因是這樣做違反了所有其他序列操作符所基於的函數式編程原則。顯然這種方法調用的唯一目的是引起副作用。

表達式的目的是計算一個值,而不會引起副作用。

...

第二個原因是,這樣做增加了零新表現力的語言。這樣做可以讓你重寫這個清透代碼:

foreach(Foo foo in foos){ statement involving foo; } 

這個代碼:

foos.ForEach((Foo foo)=>{ statement involving foo; }); 

它使用幾乎一模一樣的字符順序稍有不同。然而,第二個版本更難理解,難以調試,並且引入了閉包語義,因此可能以微妙的方式改變對象的生命週期。

+2

+1其他人已經提到過,其他人已經提前並展示了ForEach()的例子。我完全同意Eric Lippert在這裏。也許明確地張貼這個摘錄將說服OP,或者可能不。不過,IMO的最佳答案。 – Didaxis

4

最簡單的方法是定義一個foreach擴展方法,它允許你將它添加到這個排序的查詢結束。例如

public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action) { 
    foreach (var cur in enumerable) { 
    action(cur); 
    } 
} 

... 

使用方法:

newlist 
    .Where(c => c.StatusID == EmergencyCV.ID) 
    .ForEach(cur => cur.color = "Red"); 
4

List.ForEach()方法:

IEnumerable<SideBarUnit> sulist1 = 
    newlist.Where(c => c.StatusID == EmergencyCV.ID) 
      .ToList() 
      .ForEach(item => item.color = "Red"); 

PS:我知道埃裏克利珀的article aboout ForEach() vs foreach,但無論如何,它是有用的,我preffer它,而比for/foreach

編輯:關於有關性能問題的評論點擊

Enumerable.ToList()實現爲

public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source) 
{ 
    if (source == null) 
    { 
     throw Error.ArgumentNull("source"); 
    } 
    return new List<TSource>(source); 
} 

因此性能損失是創建一個新的List<>()實例的時間。

MSDN說,下一步List<>(IEnumerable<>)構造函數:

初始化包含從指定集合複製元素 並具有足夠的容量來容納複製的元素數量List類的新實例。

因此,有將所有的列表

+1

換言之,集合是可能的重複循環兩次 – Magnus

+1

雖然ForEach並不是Linq專有的「功能」。實際上,它與Linq完全無關。所以,我認爲你的答案實際上是「不,但是這是另一種選擇。」關於_ [爲什麼]的建議(http://stackoverflow.com/questions/7838458/is-there-a-way-to-set-values-in-linq/7838525#7838525)_將是一大塊輸入這個答案 - 而不是OP會帶來一個錯誤的印象,即這是Linq。 –

+0

@Mr。失望:絕對地,LINQ在'ToLisT()'調用後結束 – sll

4

的LINQ是所有關於選擇,而不是更新的複製操作。 但是你可以使用ToList和李斯特的ForEach更新的元素:

newlist.Where(c => c.StatusID == EmergencyCV.ID). 
    ToList(). 
    ForEach(su => su.color = "Red"); 

我不知道可讀性更好,但...

+0

@vs 74從IEnum <>轉換爲List <>時性能是否受到影響? – 0x4f3759df

+2

@iterationx,一個新的列表將被創建,所以它不像迭代那樣高效+我認爲它的可讀性較差,所以我不確定它值得使用這種技術...... –

2

LINQs目的主要是查詢/項目/轉換數據。

您可能想要使用ForEach擴展方法。但請參閱this discussion瞭解更多詳情。

1

你可以使用匿名方法在Select語句:

var sulist1 = newlist.Where(c => c.StatusID == EmergencyCV.ID) 
        .Select(c => { 
            c.color = "Red"; 
            return c; 
            }); 
+0

其實我不相信這會工作除非新列表被重複使用 – Davy8

相關問題