繁体   English   中英

使用 LINQ 更改列表中对象的属性

[英]Change the property of objects in a List using LINQ

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

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 };

这是我所做的,但我只得到一个列表。 我希望新列表与原始列表相同,只是某些梁的 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();

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

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

但是,这不是实现此目的的理想方法(@Jacob 的答案更好)。 查看 Eric Lippert 关于该主题的博客条目。 对我来说最重要的线路是

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

https://ericlippert.com/2009/05/18/foreach-vs-foreach/

请注意,调用ToList()是因为List<T>提供了ForEach()方法,而由于 Eric Lippert 在该博客条目中引用的原因,Linq 通常不提供此类扩展方法。

更新

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM