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

qxgroojn  于 2023-07-31  发布在  其他
关注(0)|答案(6)|浏览(180)

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

hfyxw5xn

hfyxw5xn1#

如果你的解决方案必须是完全的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()方法,而Linq通常不提供这样的扩展方法,这是Eric Lippert在博客中引用的原因。

更新

您的代码既更新原始列表中的实体(在某些条件下将IsJoist更改为 true),又返回对已更新对象的引用。如果这是您想要的,那么代码可以正常工作。然而,Linq的设计考虑到了函数范式。在Linq表达式的上下文中引入副作用违反了扩展方法背后的函数式编程原则。

vm0i2vca

vm0i2vca2#

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

字符串

busg9geu

busg9geu3#

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

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

字符串

yqyhoc1h

yqyhoc1h4#

为了功能上的纯性,你的linq不会改变它正在处理的数据。选择(x=> new Beam(x){IsJoist=true})。然后,您将使用结果替换原始列表。

ldioqlga

ldioqlga5#

我发现的最好的方法是new一个对象的副本,在select中进行修改。如果有像js那样的传播就好了。
一些未经测试的代码应该传达这样的想法:

public class Cat {
   public string Name;
   public bool IsFerrel;
}

List<Cat> cats = new{
   new{Name="Tame"},
   new{Name="Wild"}
};

return cats.Select(c => new Cat{
  Name = c.Name,
  IsFerrel = c.Name.Contains("Wild")
};

字符串
从本质上讲,这是一种不改变对象的函数方法。

igetnqfo

igetnqfo6#

您可以尝试更改列表中所有项目的属性(无任何条件)。

Beams.All(b => b.IsJoist = true);

字符串

相关问题