在LINQ Select中赋值

本文关键字:赋值 Select LINQ | 更新日期: 2023-09-27 18:13:52

我有以下查询:

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

drivers是一个列表,其中包含不同的id和更新的值,所以我正在改变选择中的值,但这是正确的方法。我已经知道我没有重新分配驱动程序给驱动程序,因为Resharper抱怨它,所以我想如果它是:

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

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

在LINQ Select中赋值

虽然这看起来很无辜,特别是与立即执行代码的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; });

但这并不是说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; 
}

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