问题描述
如何使用匿名方法或扩展名和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); }
我对其进行了测试,它可以正常工作.
问题描述
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.