在LINQ Select中分配值?

时间:2013-05-16 18:12:19

标签: c# linq

我有以下查询:

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

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

3 个答案:

答案 0 :(得分:34)

虽然这看起来很无辜,特别是与一个立即执行代码的ToList调用相结合,但我绝对不会修改任何内容作为查询的一部分:这个技巧是如此不寻常以至于会让读者感到高兴您的计划,甚至是经验丰富的计划,特别是如果他们以前从未见过这样的计划。

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

答案 1 :(得分:29)

从不这样做。查询应该是查询;它应该非破坏性地询问数据源的问题。如果您想产生副作用,请使用foreach循环;这就是它的用途。 使用合适的工具。

答案 2 :(得分: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; });

但是,ForEach上的List<T>并不合适。它可以在像你这样的情况下找到用途,但不要将变异与Linq查询混合在一起,这就是全部。我更喜欢写一些类似的东西:

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

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

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

我个人喜欢ForEach as a terminating call to Linq expression上的IEnumerable<T>(即,如果分配不是查询而是执行)。