Lambda表达式 - 根据集合中另一个属性的值设置对象集合中一个属性的值

10

我对 lambda 表达式不熟悉,希望能利用该语法根据集合中的另一个值设置集合中一个属性的值。

通常我会使用循环:

class Item
{
    public string Name { get; set; }
    public string Value { get; set; }
}

void Run()
{
    Item item1 = new Item { Name = "name1" };
    Item item2 = new Item { Name = "name2" };
    Item item3 = new Item { Name = "name3" };

    Collection<Item> items = new Collection<Item>() { item1, item2, item3 };

    // This is what I want to simplify.
    for (int i = 0; i < items.Count; i++)
    {
        if (items[i].Name == "name2")
        {
            // Set the value.
            items[i].Value = "value2";
        }
    }
}
1个回答

20

LINQ通常用于选择数据,而不是修改数据。但是,您可以编写类似这样的代码:

foreach(var item in items.Where(it => it.Name == "name2")) 
  item.Value = "value2";

首先,它选择需要修改的项目,然后使用标准的命令式循环修改所有项目。您可以使用可用于列表的ForAll方法替换foreach循环,但我认为这并没有带来任何优势:

items.Where(it => it.Name == "name2").ToList()
     .ForEach(it => it.Value = "value2");

请注意,您需要在中间添加ToList,因为ForEach是一个仅适用于List<T>类型而非所有IEnumerable<T>类型(就像其他LINQ方法一样)的.NET 2.0功能。如果您喜欢这种方法,您可以为IEnumerable<T>实现ForEach

public static void ForEach<T>(this IEnumerable<T> en, Action<T> f) {
  foreach(var a in en) f(a);
}

// Then you can omit the `ToList` conversion in the middle 
items.Where(it => it.Name == "name2")
     .ForEach(it => it.Value = "value2");

无论如何,我更喜欢使用 foreach 循环,因为这也清楚地表明你正在进行一些变异操作 - 而且在代码中轻松地看到这个事实是很有用的。


美丽。没有绕过循环的方法吗? - Michael Rut
@Michael Rut,循环比ForEach方法更易读,但这是个人观点问题。我同意Tomas在他的回答中关于行动清晰性的说法。然而,他确实展示了一种让你抽象化循环的方式(尽管明显仍会发生循环,无论你是否显式编码)。 - Anthony Pegram
如果我想在设置值后更新数据库,哪种方法对数据库的影响较小? - incomplete
性能将是相同的 - 当您提交更改时,它们都将生成相等数量的“UPDATE”语句。 - Tomas Petricek

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