2013-05-16 56 views
14

我有以下查詢:在LINQ Select中分配值?

drivers.Select(d => { d.id = 0; d.updated = DateTime.Now; return d; }).ToList(); 

驅動程序是不同的ID和更新的值是在一個列表,所以我改變選擇的值,但這樣做的正確方法。我已經知道,我不是重新分配驅動程序驅動程序,因爲ReSharper的抱怨,所以我想它會更好,如果它是:

drivers = drivers.Select(d => { d.id = 0; d.updated = DateTime.Now; return d; }).ToList(); 

,但是這仍然有人方式應該在分配新值的每個元素驅動程序列表?

+0

[Linq副作用](http:// stackoverflow。com/questions/5632222/linq-side-effects) – nawfal

回答

33

儘管看起來很無辜,特別是與立即執行代碼的ToList調用相結合,但我絕對不會將任何東西作爲查詢的一部分進行修改:這種技巧太不尋常了,它會讓程序的讀者,甚至有經驗的人,特別是如果他們以前從未見過這種情況。

沒有什麼錯foreach循環 - 事實上,你可以其與LINQ並不意味着你應該做。

+0

我會爲單行語句使用ForEach,而不是需要大括號(多語句)的東西。這裏「foreach」確實比較好。 – nawfal

+0

你是對的,它絆倒了我:)我同意你的第二個陳述。 – Xaisoft

+8

+1 LINQ不應該用於對象變異。 – recursive

28

從來沒有這樣做。查詢應該是查詢;它應該是非破壞性地提問數據源的問題。如果您想引起副作用,則使用foreach循環;這就是它的目的。 使用正確的工具進行工作。

+4

謝謝埃裏克。要知道正確的方法的唯一途徑是要知道你在做錯了第一位:) – Xaisoft

7

好的我會自己回答。

Xaisoft,Linq查詢,不管是lambda表達式還是查詢表達式,都不應該用於突變列表。因此,您的Select

drivers = drivers.Select(d => { d.id = 0; d.updated = DateTime.Now; return d; }).ToList(); 

是不好的風格。它混淆/不可讀,不是標準,也不符合Linq理念。實現最終結果的另一個差的風格是:

drivers.Any(d => { d.id = 0; d.updated = DateTime.Now; return false; }); 

但是,這並不是說ForEachList<T>是不合適的。它在像你這樣的案例中找到用途,但不要將突變與Linq查詢混合使用,即所有。我更喜歡寫這樣的:

drivers.ForEach(d => d.updated = DateTime.Now); 

它的優雅和可以理解。由於它不涉及Linq,它也不會造成混淆。我不喜歡lambda內多個語句的語法(如你的情況)。當情況變得複雜時,它的可讀性和可讀性都會降低一些。在你的情況下,我更喜歡直接foreach循環。

foreach (var d in drivers) 
{ 
    d.id = 0; 
    d.updated = DateTime.Now; 
} 

個人而言,我喜歡ForEachIEnumerable<T>as a terminating call to Linq expression(即,如果轉讓並不意味着是一個查詢,但執行)。

+0

感謝您的好解釋。 – Xaisoft

+0

@Xaisoft事實上,我討厭'列表上的'ForEach'是他們默認顯示的事實。我不認爲它適合作爲框架級別的結構。我更喜歡用戶自行決定的更高級別的構造,作爲擴展或更新。如果量身定做的東西可以幫助最終用戶,那就去做吧。這裏有很多令人討厭的東西,如果它的製作合適與否,可以由個人決定。 [這是'Type'實現的另一個'switch-case',](http://stackoverflow.com/a/1426626/661933)以及它的真棒。擁抱它或轉身離去。不要喋喋不休.. – nawfal

+0

誰在嘲笑它,它是什麼? – Xaisoft