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

Vah*_*hid 6 c# linq list

我有Beam对象列表.IsJoistWidth使用LINQ属性大于40 时,如何更改梁的属性?

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 };
Run Code Online (Sandbox Code Playgroud)

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

var result = Beams
    .Where(x => x.Width > 40)
    .Select(x => x.IsJoist = true)
    .ToList();
Run Code Online (Sandbox Code Playgroud)

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

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

Eri*_* J. 13

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

Beams.Where(x => x.Width > 40).ToList().ForEach(b => b.IsJoist = true);
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

UPDATE

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


Jac*_*nev 5

foreach(Beam beam in Beams.Where(x => x.Width > 40))
{
     beam.IsJoist = true;
} 
Run Code Online (Sandbox Code Playgroud)

  • @Vahid LINQ仅用于查询而不用于更改值. (3认同)