使用Linq更改列表的属性[英] Change a list's property using linq

本文是小编为大家收集整理的关于使用Linq更改列表的属性的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

如何使用匿名方法或扩展名和LINQ.

使以下代码较短

由于我必须多次重复此代码,因此我想使其尽可能简洁.

var imagesToUnlock = App.ImageListVM.Items.Where(img => img.Category == key);

foreach (var image in imagesToUnlock)
{
    image.IsLocked = false;
}

推荐答案

这里的其他解决方案感到肮脏,因为它们通过使用Linq在集合中突变对象.

我会相反,将代码和过滤条件放入扩展方法中,然后调用:

public static IEnumerable<Item> UnlockWhere(this IEnumerable<Item> list, Func<Item, bool> condition) {
    foreach (var image in list)
        if (condition(image)) {
            image.IsLocked = false;
            yield return image;
        }
}

保持LINQ的不变性完整,仍然产生预期的结果.

呼叫变为:

var unlockedItems = App.ImageListVM.Items.UnlockWhere(img => img.Category == key);

编辑

重新编写以完全删除LINQ.相反,此新方法仅迭代一次,并返回一个新的,突变的集合.

其他推荐答案

不是最有效的方法,但我相信您可以做

var imagesToUnlock = App.ImageListVM.Items.Where(img => img.Category == key).ToList().Foreach(f => f.IsLocked = false);

查看 foreach List<T>的方法有关更多信息.

我也想注意(某些人在评论中指出的那样),这不是某些人认为的最佳实践.您应该看一下本文 Eric Lippert,他更好地解释了这个问题.

其他推荐答案

这是一个刺伤,作为扩展方法

代码

         public static IEnumerable<T> SetPropertyValues<T>(this IEnumerable<T> items, Action<T> action)
        {
            foreach (var item in items)
            {
                action(item);
                yield return item;
            }
        }

用法

        private class Foo
        {
            public string Bar { get; set; } 
        }

        [TestMethod]
        public void SetPropertyValuesForMiscTests()
        {
            var foos = new[] { new Foo { Bar = "hi" }, new Foo { Bar = "hello" } };
            var newList = foos.SetPropertyValues(f => f.Bar = "bye");

            Assert.AreEqual("bye", newList.ElementAt(0).Bar);
            Assert.AreEqual("bye", newList.ElementAt(1).Bar);
        }

我对其进行了测试,它可以正常工作.

本文地址:https://www.itbaoku.cn/post/1557227.html

问题描述

How to make the following code shorter, perhaps using anonymous method or extensions and LINQ.

Since I have to repeat this code several times and I want to make it as succinct as possible.

var imagesToUnlock = App.ImageListVM.Items.Where(img => img.Category == key);

foreach (var image in imagesToUnlock)
{
    image.IsLocked = false;
}

推荐答案

The other solutions here feel dirty because they mutate objects in a collection via the use of LINQ.

I would instead, put the code and the filter condition into an extension method and call that:

public static IEnumerable<Item> UnlockWhere(this IEnumerable<Item> list, Func<Item, bool> condition) {
    foreach (var image in list)
        if (condition(image)) {
            image.IsLocked = false;
            yield return image;
        }
}

The keeps the immutability-concerns of LINQ intact and still produces the expected result.

The call becomes:

var unlockedItems = App.ImageListVM.Items.UnlockWhere(img => img.Category == key);

EDIT

Re-written to completely remove LINQ. Instead, this new method iterates only once and returns a new, mutated collection.

其他推荐答案

Not the most efficient way to do it, but I believe you can do

var imagesToUnlock = App.ImageListVM.Items.Where(img => img.Category == key).ToList().Foreach(f => f.IsLocked = false);

Check out the Foreach method on List<T> for more info.

I would also like to note (as some have pointed out in the comments) that this is not considered best practice by some people. You should take a look at this article by Eric Lippert, who explains the issue in better detail.

其他推荐答案

Here's a stab as an extension method

Code

         public static IEnumerable<T> SetPropertyValues<T>(this IEnumerable<T> items, Action<T> action)
        {
            foreach (var item in items)
            {
                action(item);
                yield return item;
            }
        }

Usage

        private class Foo
        {
            public string Bar { get; set; } 
        }

        [TestMethod]
        public void SetPropertyValuesForMiscTests()
        {
            var foos = new[] { new Foo { Bar = "hi" }, new Foo { Bar = "hello" } };
            var newList = foos.SetPropertyValues(f => f.Bar = "bye");

            Assert.AreEqual("bye", newList.ElementAt(0).Bar);
            Assert.AreEqual("bye", newList.ElementAt(1).Bar);
        }

I tested it and it works fine.