使用LINQ为集合中所有对象的属性分配值的最佳方法

5

我有一个 Car 对象,其中包含一个 ResaleValue 属性,我还有一个存储这些汽车对象的集合:

 IEnumerable<Car>

我还有一个ResaleCalculator(),其中包含一个calculate方法。

在linq中有没有一种方法可以应用计算并设置集合中每个对象的ResaleValue属性,而不需要循环?


2
LINQ 不是必须用于所有情况。 - jason
3个回答

16

您不应该使用LINQ。首先,它并没有避免循环,只是把循环抽象了出来。其次,LINQ 方法旨在过滤和/或投影序列,而不是改变它。虽然您可以在 List<T> 上使用 .ForEach 实例方法,从而不需要明确编写循环,但这比直接编写循环要清晰得多。


这正是MoreLinq的ForEach操作符的用途。但我相信Eric Lippert会同意你的观点,因为他曾经说过这几乎就是它一开始没有被包含的原因。 - Kirk Woll
这是最好的答案,我的答案只是“技术上”正确。有趣的是,上次我持“不要那样做”的立场时,我被踩了:o( http://stackoverflow.com/questions/4029217 而这一次我持另一种观点,一度再次被踩。我就是赢不了 :op - Iain

2

你不能修改 IEnumerable<T>,除非将其投影到一个新的 IEnumerable 中,并将这些值设置为 ResaleValue 属性并复制现有属性。理想情况下,你应该在第一次获取 IEnumerable<Car> 时就这样做。

IEnumerable<Car> cars = // however you set cars originally
cars = cars.Select(c => new Car
            {
                Prop1 = c.Prop1,
                Prop2 = c.Prop2,
                ResaleValue = ResaleCalculator(params)
             });

显然,这并不是理想的。另一方面,您可以 ToList() 您的集合并使用 ForEach 方法或普通的 foreach 循环:

var list = cars.ToList()
               .ForEach(c => c.ResaleValue = ResaleCalculator(c.SomeNeededParam));

2
我认为这将实现您想要的功能。
cars.Select(c=>c.ResaleValue = c.Calculate());

3
哦,使用Select运算符来获取Foreach运算符不管怎样都行。但我相信这是原帖想要的并且确实有效,所以点赞。 (在我看来,如果你真的想要 LINQ 风格的语法来避免使用 Select 但不使用投影会让人感到困惑,我会创建一个 Foreach 扩展方法。) - Kirk Woll
@Kirk,有趣的评论被删除了。但仍然很邪恶。 - Anthony Pegram
@Anthony,也许我不该+1,但我想合适的答案(你的)最终会提供,并且我畸形地喜欢看到所有讨论桌上的选项。 :) - Kirk Woll
1
因为我总是会盯着它想“那个是做什么的?”我喜欢事情显而易见。 - Iain
1
@jangeador:因为它在同一行代码中进行了状态变异、分支和赋值。这对于一行代码来说太多了。 - jason
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接