使用LINQ更改List中对象的属性

时间:2014-04-30 23:13:10

标签: c# linq list

我有Beam个对象的列表。当使用LINQ将IsJoist属性大于40时,如何更改梁的Width属性?

class Beam
{
    public double Width { get; set; }
    public bool IsJoist { get; set; }
}

var bm1 = new Beam { Width = 40 };
var bm2 = new Beam { Width = 50 };
var bm3 = new Beam { Width = 30 };
var bm4 = new Beam { Width = 60 };

var Beams = new List<Beam> { bm1, bm2, bm3, bm4 };

这是我所做的,但我只是得到了一个List。我希望新列表与原始列表相同,只是某些梁的IsJoist属性将设置为true。

var result = Beams
    .Where(x => x.Width > 40)
    .Select(x => x.IsJoist = true)
    .ToList();

我能够实现如下。是否可以,因为LINQ是用于查询的?

var result = Beams
    .Where(x => x.Width > 40)
    .Select(x =>
    {
        x.IsJoist = true;
        return x;
    })
    .ToList();

4 个答案:

答案 0 :(得分:11)

如果您的解决方案必须完全是Linq,那么您可以

Beams.Where(x => x.Width > 40).ToList().ForEach(b => b.IsJoist = true);

然而,这并不是实现这一目标的理想方式(@ Jacob的答案更好)。查看Eric Lippert关于该主题的博客文章。对我来说最重要的是

  

第一个原因是这样做违反了所有其他序列运算符所基于的函数式编程原则。显然,调用此方法的唯一目的是引起副作用。表达式的目的是计算一个值,而不是引起副作用。声明的目的是产生副作用。

http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx

请注意,ToList()被调用是因为List<T>提供了ForEach()方法,而Linq一般不会提供这样的扩展方法,原因是Eric Lippert在该博客条目中引用。< / p>

<强>更新

您的代码同时更新原始列表中的实体(对于某些条件,将IsJoist更改为 true )并返回对已更新对象的引用。如果这是你的意图,代码功能。但是,Linq在设计时考虑了功能范例。在Linq表达式的上下文中引入副作用违反了扩展方法背后的函数编程原理。

答案 1 :(得分:5)

foreach(Beam beam in Beams.Where(x => x.Width > 40))
{
     beam.IsJoist = true;
} 

答案 2 :(得分:1)

为了在功能上纯粹,你的linq不会改变它正在处理的数据。这意味着你必须.Select(x =&gt; new Beam(x){IsJoist = true})。然后,您将用结果替换原始列表。

答案 3 :(得分:1)

假设我想将特定对象的Property Selected的值更改为true,那么我可以这样做

Beams.Where(x => x.Width > 40).FirstorDefault(z=>z.Selected = true)