在LINQ Select中分配值?

我有以下查询:

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

drivers是一个List,它带有不同的id和更新的值,因此我在更改Select中的值,但这是正确的方法。 我已经知道我没有给司机重新分配司机,因为Resharper抱怨它,所以我想如果是这样会更好:

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

但这仍然是某人应该为驱动程序列表中的每个元素分配新值的方式吗?

虽然这看起来很无辜,特别是与立即执行代码的ToList调用结合使用时,我绝对不会修改任何内容作为查询的一部分:这个技巧非常不寻常,它会让你的程序的读者绊倒,即使是有经验的,特别是如果他们以前从未见过这个。

foreach循环没有任何问题 – 你可以用LINQ做这件事并不意味着你应该这样做。

永远不要这样做。 查询应该是查询 ; 它应该是非破坏性地询问数据源的问题。 如果你想引起副作用,那么使用foreach循环; 这就是它的用途。 使用正确的工具完成工作。

好的,我会自己回答。

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; }); 

但这并不是说List上的ForEach是不合适的。 它可以在像你这样的情况下使用,但不要将变异与Linq查询混合使用,这就是全部。 我更喜欢这样写:

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

它优雅而易懂。 既然它不涉及Linq ,它也不会混淆。 我不喜欢lambda中多个语句的语法(如你的情况)。 当事情变得复杂时,它的可读性会降低一点,而且难以调试。 在你的情况下,我更喜欢直接的foreach循环。

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

我个人喜欢在IEnumerable上的ForEach 作为对Linq表达式的终止调用 (即,如果赋值不是查询而是执行)。